微软ORM框架EF初探
一、ORM
顾名思义,ORM(ObjectRelational Mapping)对象关系映射,广义上是指面对对象的对象模型和关系型数据库的数据结构之间的相互装换。通俗来讲,就是数据库表和表实体的相互转化,包括把表实体的变化转化到数据库中以及把表数据转化成表实体。
ORM是一种思想,不管是什么平台都有自己实现ORM的解决方案,Java有Hibernate,.NET平台有EF等。
二、EF
Entity Framework(实体框架),是微软以ADO.Net为底层基础发展起来的一种重型的、跨数据库的ORM解决方案。当然,微软还有其他实现ORM的框架,如linq to sql(轻型), NHibernate等。
三、使用EF的优劣之处
1.极大提高开发效率:EF是微软产品,跟VS集成度比较好,开发中代码都是强类型的,写代码效率非常高,自动化程度高,命令式编程
2.EF提供的模型设计器非常强大,可以自动生成模板代码
3.可以跨数据库,仅需要改变配置未见就可以做到跨数据库
4.缺陷:性能差(复杂查询的时候生成的sql脚本效率不是很高)
四、EF使用Demo
1.实体数据模型生成的T4模板简单介绍
第一部分是生成的数据库上下文,DbContext是EF操作数据库表实体的基础;
第二部分是生成的设计器
第三部分是生成表实体的图解
第四部分则是生成的数据库中所有表的表实体
2. EF CURD Demo
不管增删改查,都要先声明一个上下文实例。
DataModelContainer db = new DataModelContainer();
在EF中,操作数据库中的数据不需要再去编写sql脚本,只用操作上下文的状态就能实现数据的增删改查。
增加实例,
#region 添加
//2.创建一个用户实体对象
UserInfo userInfo = new UserInfo();
userInfo.UName = "yin";
//3.将实体添加到上下文中
db.UserInfo.Add(userInfo);
//添加两个订单
OrderInfo order1 = new OrderInfo();
order1.Content = "c1";
db.OrderInfo.Add(order1);
OrderInfo order2 = new OrderInfo();
order2.Content = "c2";
db.OrderInfo.Add(order2);
//关联三个实体
//1.通过用户添加订单实体到导航属性
userInfo.OrderInfo.Add(order1);
//2.通过订单指向用户实体
order2.UserInfo = userInfo;
db.SaveChanges();
#endregion
修改、删除
不管是删除还是修改,都要拿到用户实体的id,如果只是修改特定列则只需要用lambda表达式指出所修改的列名就能实现,而且通过sql监视可发现生成的sql语句是真正的只修改了指定列。
删除的时候只需要把上下文绑定的实体对象的状态由Modified改成deleted就能达到删除效果。
UserInfo userInfo = new UserInfo();
userInfo.Id = 1;
userInfo.UName = "New" + DateTime.Now;
db.Entry<UserInfo>(userInfo).State = System.Data.Entity.EntityState.Modified;
db.Entry(userInfo).Property(u => u.UName);
查询
EF中的查询分两种,一种是标准查询运算符,使用lambda表达式进行查询,另一种则是对开发者友好的Linq查询。这两种方式运行阶段都是一样的,都转换成->Expression
只是编译时有差别,使用哪一种看个人习惯。
但是两种查询方式都是延迟加载,即查询时只有提供了IQueryable接口的几个属性,这个时候并未生成sql脚本,只有在使用到查出来的数据是才真正生成sql脚本把数据从数据库查询出来。
Linq查询
IQueryable<UserInfo> userInfos = from u in db.UserInfo.Include("OrderInfo")
where u.Id > 0 && u.UName.Contains("e")
select u;
//1.用到Linq表达式结果输出时,才执行sql脚本从数据库查询数据
foreach (var userInfo in userInfos)
{
Console.WriteLine(userInfo.Id + " " + userInfo.UName);
}
Lambda表达式查询
var data = db.UserInfo.Where(u => u.Id > 5);
foreach (var userInfo in data)
{
Console.WriteLine(userInfo.Id + " " + userInfo.UName);
}
分页查询,EF内置了非常方便的分页查询机制,而且生成的sql脚本是标准的row_number分页查询。
var pageData = db.UserInfo
.Where(u => u.Id > 0)
//.OrderBy(u=>u.Id)//默认升序
.OrderByDescending(u => u.Id)//降序
.Skip(5 * (3 - 1))
.Take(5);//越过5*(3-1)条数据取5条
foreach (var userInfo in pageData)
{
Console.WriteLine(userInfo.Id + " " + userInfo.UName);
}
部分列查询,EF中可以通过匿名类实现部分列的查询
var data = from u in db.UserInfo
select new { u.Id, u.UName, orderCounts = u.OrderInfo.Count };
foreach (var item in data)
{
Console.WriteLine(item.Id+" "+item.UName+" "+item.orderCounts);
}