第一次接触EF,但是一接触就被这个东西给吸引住了,他的功能之强大,让我有点对以前的知识都产生了EF是老大哥,而以前的是小屁孩的感觉了,唉,人就是这么的喜新厌旧。
不陶醉了,先说一下自己对EF的认识,网上查了一些资料,其实个人觉得就是一个动态的对数据库进行操作的一个技术,他的全称是Entity Framework,也就是实体框架。是的,他就是对entity的处理。在.NET发展到现在4.5版本下,他的功能也是越发的强大,就好像是JQuery一样,让我们用尽可能少的代码,来实现更好的功能。那么具体的是什么样的功能呢,容我慢慢道来。
以前我们我普通的ADO.NET链接数据库,首先是打开数据库,然后创建数据库,然后创建表,只有再写下喜爱班这么一大段代码,我们才算是链接上了我们的数据库,再对数据库进行处理。
Imports System.Data.SqlClient
Imports System.Data
Imports Entity.EntityUserInfo
Public Class LoginDAL
'数据库连接,将数据库连接定义为构造函数,当实例化 LoginDAL 的时候,自动完成数据库连接
Dim str As String = "server=.;database=Charge_System;integrated security=sspi" '这里字符串用的是windows 验证方式,所有不需要用户名和密码的操作。
Dim conn As New SqlConnection(str)
'在数据库中查询数据,执行命令语句
Public Function selectuser(ByVal model As Entity.EntityUserInfo) As Entity.EntityUserInfo
'连接数据库
conn.Open()
Dim sql As String = "select * from T_Users where UserID= '" & model.UserID & " ' and PWD= '" & model.PWD & "'"
Dim cmd As New SqlCommand(sql, conn)
'定义一个 SqlDataReader 类型的变量 reader
Dim reader As SqlDataReader
reader = cmd.ExecuteReader() '由于cmd 对象的属性 EcecuteReader 返回之是一个DataReader,所以只能定义一个Datareader类型的变量来接收数据。
'实例化一个实体层的对象 userinfo
Dim userinfo As New Entity.EntityUserInfo
'reader.read 的返回值为true 执行给 userinfo 的属性赋值操作
While (reader.Read())
userinfo.UserID = reader.GetString(0)
userinfo.PWD = reader.GetString(1)
End While
'返回 实体对象 userinfo
Return userinfo
End Function
End Class
虽然感觉逻辑不困难,可是我们每次要查询数据的时候都得重复这么一段代码,即使用了SQLHelper也是会重复性的写非常多的代码。那么我上边说的EF又强大在哪里呢。
因为我也是第一次用EF,所以这里就为也是和我一样第一次接触EF的你们详细的展示一下这个流程,看到最后你会发现EF有多么的方便。
首先打开我们的Visual Studio 2012,然后创建要给项目,我这里用的是C#,选择新建项目——>控制台应用程序(这里随便),然后我们在建好的项目中选择添加新项目。找到如下图的ADO实体数据模型
这篇博客我会先介绍从数据库中的引入.NET中,所以在选择创建实体数据模型后我们选择从数据库生成。如下图
单击下一步,出现如下图,因为我们是第一次链接,所以单机新建链接,如下图:
之后会出现我们一张再熟悉不过的图片了
选择好自己的书电脑名称,选择SQL Server身份验证,选择我们创建好的数据库,单击确定,出现如下图:
我选择的是包含敏感数据,因为如果选择否的话以后会出现一些问题,具体的是为什么,我也不知道,毕竟我也是一个菜鸟,为了避免一开始就出错误,我选择了否,大家选什么自己定下吧。接下来:
选择我们程序要用的表,然后单击完成,我们的模型就算建好了,然后大家会在解决方案中看到如下图
而我们的选择的数据库中的数据,他会帮组我们建立实体,然后保存到DataModel.Designer.cs这个类里边,然后我们就可以用着这个数据库了,是不是非常的简单。那么接下来说一下为什么我会那么崇拜EF。
打开DataModel.Designer.cs类,我们会看到public partial class: ObjectContext一个类,他就是我们中要用到的入口,是EF操作数据库的统一入口。里边包含了我们链接的数据的每个表的每个实体。那么他又是如何实现的呢。现在来实现一下
添加新数据。
EFDemoEntities db = new EFDemoEntities();
Customer customer = new Customer();
customer.CusName = "大爷";
customer.ID = 111;
db.Customer.AddObject(customer);db.SaveChanges();
这样我们就可以不用每次对数据库操作的时候进行链接了。
修改和删除数据
Customer customer = new Customer();
customer.CusName = "大爷";
customer.ID = 111;
//修改实体
//1.将当前实体附加到当前上下文中
dbContext.T_User.Attach(user);
//把上下文跟踪的数据改成修改的状态
dbContext.ObjectStateManager.ChangeObjectState(customer, EntityState.Modified);
删除数据就是把EntityState.Modified改成Deleted可以了,其他的代码不用改变。而且修改和删除更是几乎一样。
查询数据(LInQ查询)
#region linQ查询
//返回值是IQuerable
Customers item = (from b in dbContext.Customers
where b.ID == "1"
select b).FirstOrDefault();
foreach (var customer in item)
{
Console.WriteLine(customer.ID + customer.CusName);
}
#endregion
这里之所以用LinQ查询,是因为他再查询的时候是先把这些结构语句保存下来,直到真正调用的时候才回去查询数据库,这样我们就不至于还没有对准备好查询,就得链接数据库,因为数据库的查询的数据资源消耗是.NET的千倍,如果数据量太大的话会对我们的程序造成非常大的负担。当然这还不是最牛逼的地方,之所以他这么让我崇拜,是因为,下边的这一段代码。
加入有这么一个情况,顾客和订单,一个顾客有多个订单,一个订单只有一个顾客,如果我要查训每个顾客的每个订单,那么我就需要一个嵌套查询,也就是两个For循环,可是数据量小的话到还好,如果是大数据呢。但是再EF中却不存在这种情况。比如下边这段代码
var items = from c in db.Customer
select c;
foreach (var customer in items)
{
Console.WriteLine(customer.ID);
foreach (var order in customer.Order)
{
Console.WriteLine(order.ID);
}
}
尽管看上去他实现了两次循环,但是我明明只是查询了一次。但是他却只执行了两次循环,而内部的循环,EF会根据在我们开始链接数据库时中两个表的关系,自动映射出两个表中的关系,从而为我们自动查询。尽管我们只查询了一个表,但是其他的数据他也能帮我们查了。
如果没有这种机制,我们需要两个表链接,但是这么做的话,两个表都是一亿条,那么两个循环的的数据量可想而知,但是这种延迟加载,就能为我们省去大部分的时间,非常适合现在的业务,只要我们再写代码能“.”出来的都是可以的。
说到这个EF原理,是因为再EF中,所有的查询最终的返回值都是IQueryable,而他包含了查询的表达式,元素的类型,查询的驱动provider,查询驱动先解析表达式,然后再查询,拿到之后再给调用者。而我们普通的查询是直接查询,然后保存数据,当然如果我们要是经常用我们要查到的数据,我们就直接用普通的查询,那么我们每次直接调用查询到的数据。
记得以前一个师姐因为学校考试的数据,因为一个嵌套循环,服务器生成题库,用了四个小时,电脑卡了四个小时,还没有成功,仅仅是一个双循环,如果当时用了这个,估计就不会出现这个效果了,而且再EF对数据库操作中,不仅仅代码实现简单,而且效率高,这对程序员来说,能不喜欢吗。