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

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. 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一)

    相关连接导航 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二) 常用 Gulp 插件汇总 ...

  2. OVS 中的各种网络设备 - 每天5分钟玩转 OpenStack(128)

    上一节我们启用了 Open vSwitch,本节将查看当前的网络状态并介绍 Open vSwitch 涉及的各种网络设备 初始网络状态 查看一下当前的网络状态. 控制节点 ifconfig 显示控制节 ...

  3. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  4. PHP类和对象之重载

    PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的.属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值.读取.判断属性是否设置.销毁属性. ...

  5. 异步 HttpContext.Current 为空null 另一种解决方法

    1.场景 在导入通讯录过程中,把导入的失败.成功的号码数进行统计,然后保存到session中,客户端通过轮询显示状态. 在实现过程中,使用的async调用方法,出现HttpContext.Curren ...

  6. 深入.NET平台和C#编程总结大全

    对于初学者的你,等到你把这个看完之后就更清楚地认知.NET和C#编程了,好了废话不多说,开始吧!                                                     ...

  7. C语言中如何判断文件是否存在

    方法一:access函数判断文件夹或者文件是否存在 函数原型: int access(const char *filename, int mode); 所属头文件:io.h filename:可以填写 ...

  8. [转载]Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结

    本文对Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法进行了详细的总结,需要的朋友可以参考下,希望对大家有所帮助. 详细解读Jquery各Ajax函数: ...

  9. BPM流程中心解决方案分享

    一.需求分析 在过去办公自动化的浪潮中,很多企业已经实施了OA流程,但随着客户的发展和对流程管理的越来越重视, 客户对流程应用需求越来越深 入,您可能面临以下需求: 1.流程功能不能满足需求,包括流程 ...

  10. Android系统默认对话框添加图片

    开发工具Android Studio 今天公司UI要求软件对话框改成加图片的,以前没有做过,所以就学习了一下,废话不多说, 看效果: 创建XML文件dialog_lsit_item.xml <L ...