1. ORM框架之EntityFramework介绍

2016-06-25  本文已影响0人  高堂

目录

1. 自我介绍

传说中的程序猿

大家好!我是高堂。
作为一位伪前端程序猿,我给大家介绍一下微软的自家的 ORM框架

ADO.NET Entity Framework 以下简称 EF

2. 什么是EF?

ADO.NET Entity Framework

微软用来替代ADO.NET的一套 ORM 框架.

以 Entity Data Model (EDM) 为主,将数据逻辑层切分为三块,分别为 Conceptual Schema, Mapping Schema 与 Storage Schema 三层,其上还有 Entity Client,Object Context 以及 LINQ 可以使用。

EF框架 发展历史:

版本 支持.NET 发布情况 备注
EntityFramework 3.5 2.0+ 包含于.NET 3.5中 支持EDMX生成,通过扩展可支持POCO类的生成
Entity Framework 4.0 4.0+ 包含于.NET 4.0中
Entity Framework 4.X 可通过NuGet获取 支持Database First、Model First、Code First三种生成模式
Entity Framework 4.5 4.5+ 集成于.NET 4.5中
Entity Framework 5.X 4.5+ 可通过NuGet获取 支持枚举字段,性能有较大提升,支持.NET 4.0的版本 为Entity Framework 4.4
EnittyFramework 6.X 4.0+ 可通过NuGet获取
EnittyFramework 7.X 4.6+ 可通过NuGet获取 现在更名为 EntityFramework Core,结合Net Core使用,多用于跨平台

ADO.NET: 一般使用SQLHelper直接来操作数据库。

3. 什么是 ORM ?

O/R Mapping 关系图
ORM => 对象关系映射(英语:Object Relational Mapping)对于O/R,即 Object(对象)和 Relational(关系型数据),表示必须同时使用面向对象和关系型数据进行开发。

ORM框架 用途 => 为了解决 软件项目数据库 打交道的中间层。

为什么需要 ORM框架 呢?

因为软件项目 是面向对象为基本原则; 而 数据库 则是从数据理论发展而来的;两套理论存在明显的的差异。

ORM框架 到底是什么呢? 我还是不太清楚!!!
ORM 其实有三大核心原则:

简单的说 ORM 相关于中继数据。具体到产品上,例如 ADO.NET Entity Framework 实体类的属性,就算是一种中继数据。在后面我会给大家详细介绍 EF框架

4. EF 与 ADO.NET 有关系吗?

EF首先生成sql,再调用ado.net访问数据库,最后使结果对象具体化.

5. EF 与 ADO.NET 的对比——EF优势何在?

6. 世面上有哪一些 ORM 产品呢?

7. EF的开发模式

EF的开发模式

从4.1版本开始,EF开始支持三种开发模式

我们称之为“数据库优先”,前提是你的应用已经有相应的数据库,你可以使用EF设计工具根据数据库生成数据数据类,你可以使用Visual Studio模型设计器修改这些模型之间对应关系。

我们称之为“模型优先”,这里的模型指的是“ADO.NET Entity Framework Data Model”,此时你的应用并没有设计相关数据库,在Visual Studio中我们通过设计对于的数据模型来生成数据库和数据类。

我们称之为“代码优先”模式,是从EF4.1开始新建加入的功能。使用Code First模式进行EF开发时开发人员只需要编写对应的数据类(其实就是领域模型的实现过程),然后自动生成数据库。这样设计的好处在于我们可以针对概念模型进行所有数据操作而不必关系数据的存储关系,使我们可以更加自然的采用面向对象的方式进行面向数据的应用程序开发。

8. Entity Framework 增删改查

8.1 增加对象

DbEntity db = new DbEntity();
//创建对象实体,注意,这里需要对所有属性进行赋值(除了自动增长主键外),如果不赋值,则会数据库中会被设置为NULL(注意是否可空)
var user = new User
            {
                Name = "bomo",
                Age = 21,
                Gender = "male"
            };
db.User.Add(user);
db.SaveChanges();

8.2 删除对象,删除只需要对象的主键

DbEntity db = new DbEntity();
//删除只需要主键,这里删除主键为5的行
var user = new User {Id = 5};
//将实体附加到对象管理器中
db.User.Attach(user);
//方法一:
db.User.Remove(user);
//方法二:把当前实体的状态改为删除
//db.Entry(user).State = EntityState.Deleted;
db.SaveChanges();

8.3 修改对象

方法一:

DbEntity db = new DbEntity();
//修改需要对主键赋值,注意:这里需要对所有字段赋值,没有赋值的字段会用NULL更新到数据库
var user = new User
    {
        Id = 5,
        Name = "bomo",
        Age = 21,
        Gender = "male"
    };
//将实体附加到对象管理器中
db.User.Attach(user);
//把当前实体的状态改为Modified
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();

方法二:方法一中每次都需要对所有字段进行修改,效率低,而且麻烦,下面介绍修改部分字段

DbEntity db = new DbEntity();
//修改需要对主键赋值,注意:这里需要对所有字段赋值,没有赋值的字段会用NULL更新到数据库
var user = new User
    {
        Id = 5,
        Name = "bomo",
        Age = 21
    };
//将实体附加到对象管理器中
db.User.Attach(user);

//获取到user的状态实体,可以修改其状态
var setEntry = ((IObjectContextAdapter) db).ObjectContext.ObjectStateManager.GetObjectStateEntry(user);
//只修改实体的Name属性和Age属性
setEntry.SetModifiedProperty("Name");
setEntry.SetModifiedProperty("Age");

db.SaveChanges();

8.4 使用事务:使用事务很简单,只要把需要的操作放在 TransactionScope 中,最后提交.

DbEntity db = new DbEntity();
using (var scope = new TransactionScope())
{
    //执行多个操作
    var user1 = new User
    {
        Name = "bomo",
        Age = 21,
        Gender = "male"
    };
    db.User.Add(user1);
    db.SaveChanges();
    
    var user2 = new User
    {
        Name = "toroto",
        Age = 20,
        Gender = "female"
    };
    db.User.Add(user2);
    db.SaveChanges();

    //提交事务
    scope.Complete();
}

8.5 查询:查询通过LinQ查询.

DbEntity db = new DbEntity(); 
//选择部分字段 
var user = db.User.Where(u => u.Name == "bomo")
                            .Select(u => new {Id = u.Id, Name = u.Name, Age = u.Age})
                            .FirstOrDefault(); 
//只有调用了FirstOrDefault, First, Single, ToList, ToArray等函数才会执行对数据库的查询

9. EF 查询相关

EF提供的查询方式有以下几种

9.1 原始SQL查询

在EF 4.1 新增加的DbContext 除了支持LINQ与Lambda查询外,新增了支持原始SQL查询,但是不支持ESQL与ObjectQuery查询。

DemoDBEntities context = new DemoDBEntities();
DbSet<BlogMaster> set = context.Set<BlogMaster>();
List<BlogMaster> list = set.SqlQuery("select *from BlogMaster where UserId='3'").ToList();
List<BlogMaster> listAll = context.Database.SqlQuery<BlogMaster>("select *from BlogMaster").ToList();

使用原始SQL查询,既灵活又方便维护,加上DbContext泛型处理,可以将最终的查询数据集映射成对象集合。而且SQL语句有错误时,提醒也比较明确。项目中,大家都会碰到查询条件经常变动的问题,针对这种情况我们以使用通过定制的查询模板以SQL拼接的方式解决,而不是修改代码。

9.2 LINQ To Entity and Lambda

这两种是比较常用的方式,也是效率比较高的,简洁方便,但是不灵活,如果条件变了,可能就需要修改代码。相信做过报表的人都曾为复杂的SQL语句以及SQL语句的执行效率头痛过,而LINQ和Lambda 方便就在于可以将复杂的SQL拆分出来,在内存中解决这些数据的合并筛选,并且效率要远高于SQL。我最喜欢的LINQ的一个功能就是他的分组。

DemoDBEntities context = new DemoDBEntities();
DbSet<BlogMaster> set = context.Set<BlogMaster>();
var result = from u in set.ToList()
                        where u.UserID == 3
                        select u;

var resultGroup = from u in set.ToList()
                    group u by u.UserID
                        into g
                        select g;

var list = set.Where(o => o.UserID == 3);
var listGroup = set.GroupBy(o => o.UserID);

不管是哪种方式,LINQ To Entity and Lambda EF 都是支持的。

9.3 ESQL 与 ObjectQuery

首先说明一点,目前DbContext不支持这种方式查询。ESQL同原始SQL 只是写法稍为有点区别,但是特点差不多,灵活易于维护。由于可以拼接ESQL,所以这种方式也可以应对查询条件变化。

DemoDBEntities context = new DemoDBEntities();
//DbSet<BlogMaster> set = context.Set<BlogMaster>();
string queryString = @"SELECT VALUE it FROM DemoDBEntities.BlogMaster as
                    it WHERE it.UserId > @UserId order by it.UserId desc";
ObjectQuery<BlogMaster> query = new ObjectQuery<BlogMaster>(queryString, context);              
// Add parameters to the collection.
query.Parameters.Add(new ObjectParameter("UserId",6));
List<BlogMaster> list = query.ToList();

原始SQL与ESQL 区别在于参数类型的处理,因为原始的SQL你在拼接的条件的时候要对不同的参数值类型处理,例如是where Name='tt' and UserId=6 and Sex=true ,而ESQL则是object传入,直接实现SQL语句的转换。可惜DbContext不支持ESQL,所以只能自己去解决SQL条件不同值类型的拼接处理。

9.4 ObjectQuery 查询生成器

DemoDBEntities context = new DemoDBEntities();
            
ObjectQuery<BlogMaster> query = context.CreateObjectSet<BlogMaster>()
    .Where("it.UserId > @UserId",
    new ObjectParameter("UserId", 6))
    .OrderBy("it.UserId desc");

List<BlogMaster> list = query.ToList();

这种方式基本上有ESQL相同,只是分组,排序,条件过滤都要单独处理,相比就没结合ESQL使用灵活了。

以上四种方式各有优缺点,如果是批量做页面的查询,每个查询页面和条件各不相同,并且查询条件可能会变动的话,建议使用DbContext的SQL查询,或者是ESQL结合ObjectQuery,这两种方式易于通过查询模板拼接生成SQL语句,但不适合生成复杂的SQL语句。

而LINQ or Lambda 以及ObjectQuery方式,则不适合做一些重复查询逻辑的工作,而单独处理一些页面的查询或者复杂的报表还是比较灵活的。

10. 结束语

Thanks everyone!
上一篇下一篇

猜你喜欢

热点阅读