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

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. CSS十问——好奇心+刨根问底=CSSer

    最近有时间,想把酝酿的几篇博客都写出来,今天前端小学生带着10个问题,跟大家分享一下学习CSS的一些体会,我觉得想学好CSS,必须保持一颗好奇心和刨根问底的劲头,而不是复制粘贴,得过且过.本人能力有限 ...

  2. 使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

    直接切入正题,这是我09年到11年左右业余时间编写的项目,最初的想法很简单,做一个能拖拖拽拽就直接生成应用程序的工具,不用写代码,把能想到的业务操作全部封装起来,通过配置的方式把这些业务操作组织起来运 ...

  3. WinForm 天猫2013双11自动抢红包【源码下载】

    1. 正确获取红包流程 2. 软件介绍 2.1 效果图: 2.2 功能介绍 2.2.1 账号登录 页面开始时,会载入这个网站:https://login.taobao.com/member/login ...

  4. 按需加载.js .css文件

    首先,理解按需加载当你需要用到某个js里面的函数什么鬼,或者某个css里的样式的时候你才开始加载这个文件. 然后是怎样实现的,简单来说就是在js中动态的createElem<script> ...

  5. JavaScript动画-磁性吸附

    ▓▓▓▓▓▓ 大致介绍 磁性吸附是以模拟拖拽为基础添加一个拖拽时范围的限定而来的一个效果,如果对模拟拖拽有疑问的同学请移步模拟拖拽. 源代码.效果:点这里 ▓▓▓▓▓▓ 范围限定(可视区) 先来看一个 ...

  6. pt-mext

    pt-mext实现的功能比较简单,就是将mysqladmin输出的多次迭代的相同status变量值放到同一行输出. 参数很少,除了--help和--version外,只有一个--relative参数 ...

  7. 马里奥AI实现方式探索 ——神经网络+增强学习

    [TOC] 马里奥AI实现方式探索 --神经网络+增强学习 儿时我们都曾有过一个经典游戏的体验,就是马里奥(顶蘑菇^v^),这次里约奥运会闭幕式,日本作为2020年东京奥运会的东道主,安倍最后也已经典 ...

  8. WebApi返回Json格式字符串

    WebApi返回json格式字符串, 在网上能找到好几种方法, 其中有三种普遍的方法, 但是感觉都不怎么好. 先贴一下, 网上给的常用方法吧. 方法一:(改配置法) 找到Global.asax文件,在 ...

  9. Tomcat常见问题及常用命令

    很长时间不用tomcat好多命令都忘记了,所以准备自己记录下来,以便参考.刚好也希望可以开始养成记博客的好习惯. 1.查看java的版本号 进入java的安装目录后,使用命令:java -versio ...

  10. Take into Action!

    很久没有认真地写文字了. 刚毕业一两年断断续续在csdn上写过一些当时的工作记录,然后没有坚持下去.有时候是觉得自己不牛,记录的东西旁人看起来也许不值一提:有时候觉得结婚生娃了,然后时间不够用(确实是 ...