在知乎回答了下,顺手转回来。

Enity Framework已经是.NET下最主要的ORM了。而ORM从一个Mapping的概念开始,到现在已经得到了一定的升华,特别是EF等对ORM框架面向对象能力的升华。切实地说,就是ORM让数据库在整个应用过程中更好地被封装和抽象化。

ORM一开始只是Mapping,最基础的就是表与类的对应、Column和属性的对应,这只是最基础的。在这个层次上,数据库对象通过Mapping在面向对象语言层面,也就是业务层面被封装成了业务对象,然后允许以操作业务对象的方式对数据库进行操作。

但是,在很长时间里,ORM的提升都被对象与关系间的“阻抗失配”困扰。一直以来很多ORM的水平都只是维持在了用对象的方式进行CRUD而已,除了减少代码错误、提高简单查询的开发效率,在复杂查询、性能等等一些方面结果都还是要跨层回到底层的操作框架比如ADO.NET甚至存储过程去解决问题。

所以,在应用场景上来说简单查询的场景EF和其他ORM都是能够胜任的。

从应用场景说起,这点在B/S和C/S里也会很明显。用户使用Web的时候和使用桌面软件的最大体验不同是什么?——所见即所得。你在网页上操作了半天,一个关闭就全没了,还必须提交然后获得下一个页面才能把数据状态和UI更新;而同样在桌面上,你的操作比如画图,在操作的一瞬间结果就出来了。当然了,Web 2.0技术就在解决这个问题。

同样在OO和RDBMS中的问题也在这里。

从OO的角度上看,你运行下一段代码结果如何:

user.Name = "Indream Luo";

在OO里,就是user对象的Name属性被更新了。如果是一个桌面软件,那么用户的名称应该也更改了。

但是如果这个对象的数据是存在关系数据库中,或者任意数据库,那么结果都逃脱不出这个套路:

var object = db.Get(id);
change(ref object);
db.Update();

你需要把更新Push过去,将操作和数据持久化。

在存储分层开始,推送更新就不可避免,哪怕在说面应用中,也是将对象的更新推送到了UI。ORM站立在应用场景不一致中间所要扮演的角色,就是一个润滑剂的角色。

在我所能马上想起的特性,就是EF和NHibernate的缓存机制。EF是一级缓存,NH是二级缓存,手动的话似乎EF也可以做到二级。然后在.NET下最重要的一点是有LINQ。LINQ在有合适的Provider的情形下可以把OO的序列化操作转化成目标的序列化操作,在这里就是LINQ转SQL,这样就省去了拼接SQL、SQL注入等很多麻烦。另外LINQ延迟加载的特性也很大地减少了用户控制SQL执行的工作。

在操作同步的基础上,还有结构同步的问题。表结构和对象结构同步是使用ORM一大工作内容。EF有默认的生成工具,DB First、Model First、Code First三种模式提供选择,加上自动生成同步SQL,选择性是现在最广的,NH也有一些相应的生成器,数据库优先方面小弟LINQ to SQL的拖拽最惊艳。

在这个场景下,加上对相关工具的利用,EF等ORM适用于序列操作、减少数据库操作管理和结构同步工作量,减少开发成本。

最后,不可回避的就是阻抗失配的问题。
对象关系模型和关系数据库模型在以前很大程度上不一致,这是在以前。现在ORM要做的就是如何让两者更接近,让一边的特性能更顺滑地体现在另一边。

我 在早几个月写过一篇总结,关于最近一个项目EF使用的一些方法——《Entity Framework 与 面向对象》。太长就选重点来说明。

EF所做的涵盖:类型匹配、对象结构、数据源区分。

类型匹配方面,就是把OO类型和数据库类型进行匹配,这是ORM的基础。基础类型中的整数、浮点、字符串、日期这些不在话下,EF比较有特点的可能是枚举类型(Enum)、复杂类型(Complex Type)、地理位置的功能,实现方式也比较理想。

对象结构方面是EF让我最惊艳的地方。EF的Model,也就是Entity能实现集成关系,也可以通过此同步在表结构中;EF中通过对外键的控制,对引用和依赖关系实现得十分出色;支持虚类、对象层面的Get/Set、访问控制都很好用。

插一段,通过使用Model First,我倒是发现数据库的设计更加接近于范式了。因为LINQ和对象结构方面带来的便利,我可以把表结构设计得更“合理”。比如如果要获取user的上司的上司,假设每个User都只有一个上司,那么用EF或者一些ORM就是:

var bigBoss = user.Superior.Superior;

如果要写SQL,感觉有点烦,算代码量和可读性已经能看出区别了。

最后是数据源区分。有一个问题是一个对象,它的数据不一定完全源于数据库,或者一个数据库,这个例子我常用。
比如User有三个字段:FirstName、LastName、FullName。可以知道FullName其实就是FirstName和LastName的拼接,如果创建Model/Entity,一般:

public partial class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get
{
if (fullName == null)
{
this.fullName = String.Format("{0} {1}", this.FirstName, this.LastName);
}
return this.fullName;
}
} string fullName;
}

而在数据库里,只需要存储FirstName和LastName,FullName作为计算值就可以了,而且还是延迟加载的。

更甚者,我们还可以从上面的例子延伸,在Entity中封装一些数据库操作:

public partial class User
{
public User Superior { get; set; }
public User BigBoss
{
get
{
return this.Superior.Superior;
}
}
}

此时在数据库中只存储一个Superior关系即可,BigBoss作为计算值就可以了。当然,你乐意还可以缓存和延迟加载,但EF已经处理了缓存了。

极端情况,确实是可以在表关系中“玩”不少面向对象的设计模式。

终上所述,EF适用于面向对象结构和特性优先性比较高的 场景。

那么相对地,也说说不适用的场景。

首先大家所诟病的是性能问题,这点希望不要抛开原理去说EF的性能

EF由于其执行原理,性能损耗一般发生在:

  1. LINQ也就是Expression Tree创建和转换成SQL的过程
  2. 缓存比对的过程
  3. 特殊操作实现不合理
  4. 极限性能压力下的问题
  5. 性能泄露

1是不可避免的,2通过关闭比对或者缓存可以解决,3、4和5是主要问题。
特殊操作不合理举例来说,比如递归,获取一个树结构的一条索引链。如果是通过OO来做,那么就是要么要往返很多次数据库,要么要至少遍历一次对象表,要么就是要加一些特殊的“丑陋的”索引字段。
极限性能压力在包含上个问题的情况下扩展,比如SQL Server的存储过程执行的特殊操作是最快的,纯OO的方式肯定达不到。
这两项特殊项通过更原生的数据库方式去解决是最佳的解决方案。你可以和EF混用,也可以单独使用,但不要妄想着有银弹能同时解决所有问题。EF提供了SQL的执行方式。
性能泄露不是一个专有名词,是我临时用的。意思是因为EF导致的不必要的性能浪费。特别是LINQ的延迟加载特性,许多不清楚LINQ特性的开发人员容易将LINQ序列无谓地实例化,浪费了系统资源。通常会是:

  • 遍历查询全表数据, 然后再在OO层面进行筛选
  • 无谓地执行实例化,进行查询,要么浪费缓存比对的资源,要么浪费查询资源

我只能说这是开发人员水平问题,虽然出现问题后很难定位,特别是一般情况下都会造成内存泄露。

最后最常见的还是回到数据模型同步的问题。当数据模型更改后,需要同步,这时候如果已经有业务数据了,是一件麻烦的事情。EF的Migration我没用过,是一个解决方案但似乎不那么完美。在一些非ORM应用的系统,SQL集中管理架构下,在这个场景,可能会更容易进行维护。

ADO.NET Entity Framework 在哪些场景下使用?的更多相关文章

  1. ADO.NET Entity Framework

    ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案, 早期被称为 ObjectSpace,现已经包含在 V ...

  2. ADO.NET Entity Framework学习笔记(3)ObjectContext

    ADO.NET Entity Framework学习笔记(3)ObjectContext对象[转]   说明 ObjectContext提供了管理数据的功能 Context操作数据 AddObject ...

  3. 让ADO.NET Entity Framework 支持ACCESS数据库

    如写的不好请见谅,本人水平有限. 个人简历及水平:. http://www.cnblogs.com/hackdragon/p/3662599.html 接到一个程序和网页交互的项目,用ADO.NET ...

  4. ADO.NET Entity Framework Extensions

    一.情景 如果你的项目中有返回多结果集的存储过程. 如果你的项目要和老项目中的ADO.Net共用事务. 如果你要动态的创建数据库的表. 但是你还是希望使用Entity Framework.那么继续往下 ...

  5. APS.NET MVC + EF (02)---ADO.NET Entity FrameWork

    2.1 Entity Framework简介 Ado.net Entity Framework 是Microsoft推出的ORM框架. 2.1.1 什么是ORM 对象关系映射(Object Relat ...

  6. ADO.NET-EF:ADO.NET Entity Framework 百科

    ylbtech-ADO.NET-EF:ADO.NET Entity Framework 百科 ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 ...

  7. ADO.NET Entity Framework CodeFirst 如何输出日志(EF 5.0)

    ADO.NET Entity Framework CodeFirst 如何输出日志(EF4.3) 用的EFProviderWrappers ,这个组件好久没有更新了,对于SQL执行日志的解决方案的需求 ...

  8. 如何得到EF(ADO.NET Entity Framework)查询生成的SQL? ToTraceString Database.Log

    ADO.NET Entity Framework ToTraceString  //输出单条查询 DbContext.Database.Log  //这里有详细的日志

  9. Microsoft SQL Server Compact 4.0&&ADO.NET Entity Framework 4.1&&MVC3

    最近重新查看微软MvcMusicStore-v3.0的源代码,发现忽略了很多重要的东西,特别是数据访问那一部分. 首先Microsoft SQL Server Compact 4.0 详细的介绍和下载 ...

随机推荐

  1. [APUE]UNIX进程的环境(下)

    一.共享库 共享库使得可执行文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这种库例程的一个副本.程序第一次执行的时候或第一次调用某个库函数的时候,用动态链接方法将程序与共享库函 ...

  2. 苹果强制使用HTTPS传输了怎么办?——关于HTTPS,APP开发者必须知道的事

    WeTest 导读 2017年1月1日起,苹果公司将强制使用HTTPS协议传输.本文通过对HTTPS基础原理和通信过程内容的讲解,介绍APP开发者在这个背景下的应对办法. 几周前,我们在<htt ...

  3. Servlet监听器笔记总结

    监听器Listener的概念 监听器的概念很好理解,顾名思义,就是监视目标动作或状态的变化,目标一旦状态发生变化或者有动作,则立马做出反应. Servlet中的也有实现监听器的机制,就是Listene ...

  4. Performance Monitor4:监控SQL Server的IO性能

    SQL Server的IO性能受到物理Disk的IO延迟和SQL Server内部执行的IO操作的影响.在监控Disk性能时,最主要的度量值(metric)是IO延迟,IO延迟是指从Applicati ...

  5. WCF基础

    初入职场,开始接触C#,开始接触WCF,那么从头开始学习吧,边学边补充. SOA Service-Oriented Architecture,面向服务架构,粗粒度.开放式.松耦合的服务结构,将应用程序 ...

  6. 【JS基础】循环

    for 循环的语法: for (语句 1; 语句 2; 语句 3) { 被执行的代码块 } 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块)的条件 语句 3 在循环(代码块)已被 ...

  7. 满堂红CIO邓劲翔:房屋中介突围

    人脸识别.客户关系管理进度监控.业务流程实时监控.网站访问人数及流量实时监控等实际企业应用场景淋漓尽致.羽羽如生的以大屏幕上图表形式展现在人们面前,如果你不去继续询问,你不会知道这是一家才刚刚在房地产 ...

  8. iOS开源项目周报1229

    由OpenDigg 出品的iOS开源项目周报第三期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. Ma ...

  9. 设置Hyper-V和VMware多个服务之间共存

    这个方法是解决多个服务之间不能共存,下面相当于是以Hyper-V和VMware做例子,其他的也适用. 今天准备安装VMware Workstation 10,然后玩玩MAC OS. 没想到,淡定的我双 ...

  10. 修改MySQL默认字符集编码

    好记心不如烂笔头,很多东西当时没记下来,过了就忘了,下次用到时又得浪费好多时间才能解决.今天又遇到修改MySQL默认字符集编码的问题,折腾了半天解决了,赶快记录下来,以后就不用每次折腾了. 查看MyS ...