Asa*_*f R 60 .net ado.net entity-framework .net-4.0
我正在为一个大项目决定一个ORM,并决定选择ADO.NET实体框架,特别是它随.NET 4提供的新版本.在我搜索有关EF的信息时,我偶然发现了ADO .NET实体框架投票不信任,我不知道该怎么做.
2008年的某个时候写下了"不信任投票",以说服微软听取对EF v1的具体批评.
目前尚不清楚在"不信任投票"中提出的声明是否仍然有效(在.NET 4中)以及它们是否足够严重以至于使用其他解决方案.NHibernate是一个成熟的选择,但我不知道它带来了什么问题.我通常更倾向于使用Ms解决方案,主要是因为我可以指望与VS的集成以及他们的开发人员支持.
我将不胜感激例子在不信任的投票提到的问题是如何在现实世界中的项目的影响.更重要的是,那里的声明是否仍然与EF for .NET 4相关?
Cra*_*ntz 64
我一直认为,"不信任投票"的大部分内容都是尝试使用EF,好像它是NHibernate克隆一样.它不是,甚至在EF 4中尝试使用EF就好像它是NHibernate的仿冒品可能会以失败告终,尽管你可能会在失败前稍微进一步.作为一个简单的例子,大多数人在NHibernate中使用LINQ是最小的,如果有的话,我认为除非你非常使用LINQ,否则你根本不会在EF 中有效.
另一方面,我已经非常成功地按照自己的条件使用EF 1,并且设法不允许人们在博客文章中提出的声明妨碍我使用它.我期待使用EF 4中的许多新功能,但我很乐意随时使用结构良好的EF 1项目.(就此而言,我也很高兴与NHibernate一起工作,并且不会批评它不像EF一样.)
因此,我试图以一种微妙的方式建议,在您决定"在不信任投票中提出的声明是否仍然有效(在.NET 4中)......"之前,您必须首先确定这些声明是否有效是以往任何时候都适用于你的方式和你的工作.如果你对O/R的个人理解与NHibernate很难相连,那么EF 4对你来说可能仍然是次要的.另一方面,如果你愿意学习EF工作方式,那么即使EF 1看起来也会比你听到的更好.
直接解决"不信任"主张,并检查其实质内容和EF 4中的变化:
顽固地关注实体的数据方面导致已降级的实体架构:
这是对实体框架实体数据模型的误解.(或者,如果你愿意的话,意见分歧.)但不管怎样,它都是一个特征,而不是一个bug.实体框架是围绕更一般的数据服务案例而设计的,而不仅仅是O/R建模.将行为放在从数据服务返回的实体上会导致CORBA风格的灾难.与ORM不同,ORM在某种程度上坚持使用ORM黑盒中出现的任何类型,使用Entity Framework模型,您需要将其投射到业务类型上.在这种情况下,映射的实体类型将永远不会实现.
这是实体框架模型与许多其他ORM之间的实质性差异.就个人而言,我发现将业务行为与O/R映射分离比将它们集中在一起要清晰得多.你不必同意这个想法,但这显然是一个设计决定,而不是一个疏忽.
需要处理缺乏懒散负担的额外代码:
无论好坏,EF 4都有延迟加载.
我说"为了更好或更坏",因为延迟加载使得生成多余的数据库查询变得非常容易.只要你密切关注引擎盖下发生的事情,它就可以正常工作,但大多数人并不这样做.我发现投影是延迟加载,急切加载或大部分时间显式加载的更好选择.
有时,延迟加载很方便.所以我很高兴看到它在EF 4中添加了.
共享,典范模式的矛盾软件最佳实践:
很难知道如何做到这一点,因为一些支持文本甚至不是连贯的英语,例如:
对于缺乏基于实体框架的复杂工具而言,容易出错的规范模型方法并不困难.
本节似乎表明,实体框架对复杂系统使用单一的规范数据模型提出了某种要求,或者至少是强烈的偏见.我不确定我是否同意,但由于本节中没有任何具体的例子,我很难说.所以我会告诉你我对这个问题的偏见,你可以同意或不同意我:
根据系统实际的大小,将单个模型用于大型系统通常是错误的.但是,实体框架中的任何内容都不要求您使用单个模型.另一方面,实体框架,特别是在版本1中,并不是为了简化组合多个模型的方式.
现在,复杂系统的单个大型应用程序可能与单个大型数据模型一样大.因此,实体框架很容易将许多小模型组合成一个过大的应用程序; 这只会将一个问题替换为另一个问题.
另一方面,我认为通过以适合问题域的方式分区的服务构建大型系统很容易.我认为WCF数据服务是一个与实体框架不同的技术,但是很好地支持实体框架,对此非常有用.
我确实认为实体框架在未来的某个版本中可以在必要时更容易将两个或三个模型组合到一个应用程序中.您现在可以执行此操作,但涉及一些手动工作.但正如我上面所说,我不想通过促进/鼓励创建过大的应用程序来"修复"过大数据模型的问题.
缺乏持久性忽视导致商业逻辑变得难以阅读,写入和修改,导致开发和维护成本以增加的速度增加:
本节提出我认为错误的说法:
实体框架通过阻止在实体类中包含业务逻辑来鼓励Anemic Domain Model反模式.
往上看.我认为实体类型的工作是在对象空间中的关系空间之间进行映射.根据单一责任原则,这些类型只需要在其唯一的工作变更时进行修改.如果业务流程发生变化,那么这是与O/R映射无关的责任.或许其他ORM的局限性对分离这些责任施加了技术障碍.如果设计纯度的成本过高,那么在技术要求下弯曲规则是可以的.但我强烈赞成无行为实体类型的方法.
在其当前状态下,EF实体类不能独立于数据库进行有效的单元测试.
这是错的.写这篇文章的人不明白他们在谈论什么.我们的单元测试都没有触及DB,而且很多都涉及到EF.
就本节标题的内容而言,EF 4有一个变化.现在可以有完全持久性无知的实体类型,如果这有助于你的设计.但是,从最早版本的实体框架开始,您已经能够投射到POCO上.因此,在需要时始终可以获得持久性无知.对实体类型本身具有持久性无知允许使用持久性无知对象进行更改跟踪.这在某些情况下可能有用.但是,与单元测试的虚假声明相比,它只是一个相当小的案例子集,这减少了文档所产生的重点的影响.
在团队环境中对源控制的过度混合冲突:
合并XML真的那么难吗?如果是这样,也许应该考虑一个新的合并工具.我没有发现这个问题.
然而,这里存在一个真正的问题,尽管它再次比文件声称的要窄得多.我不会重复自己,而是指向你关于这个主题的帖子.
在EF 4中,可以使用代码优先模型而不是XML模型,以便将模型拆分为许多不同的文件.
编辑:这使用是正确的,但它不是任何人.
作为一个使用过Entity Framework和NHibernate的人......我强烈建议使用NHibernate.通常情况下,如果存在FOSS和MS技术,我建议使用MS技术,但我强烈反对EF.我在工作中每天使用EF4,因为EF,我们必须创建大量的解决方法.两年前我使用EF大约一年,然后我改变了公司,过去一年我一直在与EF合作.2年前,NHibernate领先于EF4.
这是他们提出的要点.
从我听到的情况来看,这部分是固定的.他们将设计师的位置数据移动到.edmx的底部,所以它不再是一个可怕的问题,但仍然很烦人.如果我和同事都尝试同时修改.edmx,我们往往会遇到可怕的合并冲突,因为文件的整个底部用于存储设计器中表的位置数据.我们解决此问题的方法是使用SVN文件锁定,因此我们不会对其进行双重编辑.或者我忽略了锁定,如果我遇到合并冲突,我只是接受他们的更改并重做我的工作.我的大部分变化都不是很大,他们需要很长时间才能重新做.如果这是唯一的问题,我会忍受它.
如果您使用的是代码优先(在EF 4.1中),则这不是问题.
他们在4.0中添加了延迟加载.
但它的装载仍然像一块垃圾一样.急切加载很慢,这是您需要加速代码时的常见优化.我遇到的情况是,当我宁愿使用急切加载时,我必须对数据库进行10k +调用.我们已经定时了,在很多情况下,myobject.TablenameReference.Load()对本地数据库进行多次数据库调用(在循环中执行)然后使用它会更快.Include("Tablename").是的,我知道这是非常反直觉的,但数字不是谎言.此外,无法指定fetch stragety,因此您无法指定Join-fetch.所以我说它有所改进,但不如NHibernate好.
是的,这仍然是真的.再一个很好的例子就是order.Status.我们真的希望它是一个枚举,但由于EF的设计方式,我们除了将它作为一个字符串之外别无选择.他们可能会在将来修复枚举问题,但是在表和对象之间进行映射的方式之间缺乏控制是真正的抱怨.NHibernate允许您指定执行映射的方法,以处理这种情况.
为了扩展Craig Stuntz的响应点,如果您想要获取数据模型并直接从中选择,则设计EF.(IE myModel.Orders.Where(order => order.Status == "NEW").Select(order => order.Customer.FirstName, order=> order.Customer.LastName).)如果您不想打开数据库,EF的模型最终会很难编写自动化测试.如果你想要一个存储库,你要求一个符合某些条件的对象,并返回整个对象,这就是NHibernate更好地工作的地方.(IE var order = myOrderRepository.GetByStatus(OrderStatus.New)).
我对EF的另一个问题是它完全缺乏可扩展性.我们遇到的一个问题是我们有订单状态的枚举.但是如果我们这样做myModel.Orders.Where(order => order.Status == OrderStatus.New.ToString()),EF将在该查询上崩溃,因为它不知道.ToString()方法.它大大增加了我们的代码,因为我们无法添加对它的支持.还有很多内部方法,所以我们需要引起奇怪的行为,我们不能这样做.
如果您正在使用NHibernate,Linq为nhibernate添加了许多功能,使其更好.使用基于约定的模型,对于大多数映射,它只需要很少的代码.如果您正在使用现有数据库,Nhibernate允许您指定要使用的非标准约定,然后将它们映射,并且一切都很容易管理.EF 4.0(我不认为4.1)不支持任何类似的东西.
我希望这能够帮到你.
| 归档时间: | 
 | 
| 查看次数: | 4012 次 | 
| 最近记录: |