与我之前的许多开发人员一样,我正处于选择ORM进行彻底学习和未来项目前进的十字路口。我一直在玩Entity Framework,到目前为止,就像我看到的那样,虽然我只尝试了简单的东西,CRUD与明确定义的表关系和1-1表实体映射。 我在实体框架上做了一些谷歌搜索并发现了大多数负面反馈......我最关心的是映射xml和生成的对象类的复杂性......以及它们依赖于EF的组件类和因此,在涉及对象模型设计考虑因素时需要得到尊重。到目前为止,我倾向于NHibernate ......因为映射文件的相对简单性以及它可以与我制作的POCO对象一起工作以满足我的对象模型设计需求。甚至还有一个LINQ提供商,以及第三方代码生成工具。 但是......我不想把EF抛到窗外。有谁知道用EF编写的成功的制作应用程序?或者在技术方面,我现在想要倾向于EF的任何原因,例如拥有企业支持,是新的,因此随着时间的推移,当NH达到成熟的均衡时,更有可能在功能集中增长? 我并不是要在这里开始色彩战争,我只是在寻找人们在做出决定之前可能需要添加的关于EF的积极的事情。
谢谢!
答案 0 :(得分:14)
虽然我倾向于同意蒂姆关于框架选择的“宗教”因素,但我仍然觉得有点奇怪,很多人都愿意评论EF,因为他们显然没有费心去学习如何作品。事实证明,EF将是一个糟糕的NHibernate版本,就像锤子制作糟糕的螺丝刀一样。按照自己的条件理解EF非常重要。
在我解决此处评论中提出的一些观点之前,我将补充一点,我们刚刚发布了生产网络应用程序的第2版,其中包含0行SQL和100%的所有数据库访问,通过EF或我们的客户的ASP.NET成员资格API。我在这里讲的是使用EF的真实经验,遗憾的是,到目前为止我所看到的关于EF的大多数评论的作者显然都不是这样。
一般来说,我认为扩展您的实体类型是错误的。蒂姆引用的博客文章的作者(1)并不知道这是可能的,并且(2)认为这是实施DDD的途径告诉我所有我需要知道的关于他的真实EF体验:他没有。
POCO支持对某些ORM的用户来说是一个非常大的交易,因为他们多年没有实现LINQ功能。由于您基本上坚持使用黑盒子中出现的任何类型对象,因此控制父类型变得非常重要。事实上,如此大,用声明public virtual
的每个成员写你的“POCO”开始被视为没什么大不了的。在哪个星球上这是一个“普通”类型?它是代理基础,而不是POCO。所谓的“POCO”根本不是POCO。只是他们更喜欢在封装和性能上而不是父类型上妥协。在他们的工具集的限制范围内,这可能是一种合理的妥协,但没有什么值得骄傲的。
但EF的工作方式不同;通过LINQ投影作为实际映射的类型,可以很容易地实现任意类型。如果您正在构建通过线路发送对象而不是在内部使用的东西,并且必须具有不依赖于EF的客户端,那么您可以使用RIA服务或编写ADO.NET数据服务。所有的辛勤工作都将为您完成。 EF是一系列工具的基础,用于处理将数据库中的数据投影到各种类型的客户端上的问题,而不是一个独立的工具,它试图在一个胖框架内处理应用程序内部可能需要的每一个数据转换。让EF处理从RDBMS到对象空间的投影。然后,您可以使用LINQ to Entities投影到持久性无知类型,或者使用RIA服务投影到Silverlight友好的有线格式。要求一个工具处理任何应用程序可能需要的每个投影,就是乞求用这个工具卡在贫民窟中。
EF基于“价值对象”的概念。这些是具有属性但没有行为的类型。事实证明,值对象对于某些特定问题非常有效,例如通过线路发送数据或坐在RDBMS和OO编程之间的“无人区域”。 理解这里关注点的分离非常重要:实体类型的要点是将RDB 数据引入对象空间。然后,您可以编写实现应用程序的业务类型,并将实体类型投影到业务类型上。然后,您可以自由地实现业务类型,而不会对持久性做出妥协。您可以在需要时更改RDB架构。您只需要更改实体映射和BO投影,而不是BO本身。
答案 1 :(得分:3)
我摆脱了Entity Framework 4.1并且从未再次使用它,原因如下:
有很多爱好者的好文章和博客都知道它的内外,但是,嘿,它与查阅参考文献不一样,为什么我希望有人比官方来源的官方文件更好地了解它?为什么微软不打算为其旗手数据访问技术提供更好的手册,以涵盖超出其一年级书籍范例的方法?缺乏有关如何使用它的信息会使学习曲线更加陡峭,导致浪费时间和错过最后期限。
没有办法进入它,看看它想要做什么。 这是一个非常精心打造的黑匣子。尽管主张使用IoC和依赖注入,微软的团队很少在自己的产品中遵循这些原则。实体框架也不例外。大多数核心类都标记为密封(EntityConnection,MetadataWorkspace),因此您无法覆盖方法并查看内部发生的情况。 ToString()方法仅适用于查询。如果你想看到通过将POCO堆叠到数据上下文并运行SaveChanges而生成的真实SQL语句,那么就忘了它,没有办法做到这一点。具有讽刺意味的是,根本没有变更集的概念,因此封装了一系列修改的内容隐藏在内部,并且从未暴露给开发人员。我的意思是说到CUD操作时没有任何东西可以调用ToString()。
“友好”错误消息。几乎每个错误消息都是一个拼图,平均需要30分钟的谷歌搜索和阅读受挫的开发人员的讨论。为什么如此难以将一些有助于解决问题的信息放入该错误消息中?如何“从数据库获取提供程序信息时发生错误”。比“未知错误”更好?
我觉得我无法控制正在发生的事情以及我在每个特定时刻的位置。根据显式请求,实体可以延迟加载,缓存或从数据库中拉出。我无法通过查看对象的状态或源自何处来判断。它是陈旧的,悬挂的还是附在上下文中的事件?当我将它链接到另一个实体时,实体框架是否会确保它仍在数据库中?您所接触的只是您的POCO对象,传统集合以及DbContext中的其他几种方法。等等,IDbSet(类似ICollection)接口是数据库能够进行的所有操作的超集吗?承认数据库稍微复杂一些,因此需要特殊的接口和可以清楚地传达意图的其他对象,这不是更公平吗?鉴于实体框架所做的不仅仅是拉动和推送数据,那么在你看到它的时候让Cached<TEntity>
和LazyCollection<TEntity>
这样的东西告诉你这个故事会不会更有意义呢?尝试将ADO.NET压缩到ICollection和接口等同样牺牲了简单的重要细节并不是一个明智的想法。它会损害理解的容易程度,并为意外错误留出更多空间。我的意思是对象模型需要密切反映域。您不能忽略它或隐藏Database类的静态方法的差异。
总而言之,我花了更多时间盲目地尝试所有不同的方法来使其工作,而不是专注于真正的问题。我发现即使ADO.NET需要更多的输入,结果仍然保证在有限(而不是非常糟糕)的时间内,而使用实体框架,您可以花费几天但却什么也得不到。这是一个巨大的破坏。所以底线是:实体框架不能帮助您解决您的业务问题。它可以帮助您浪费时间与另一个设计糟糕/文档化的技术不断斗争,只是为了使用它和使用LINQ语法进行简单查询的乐趣。不要冒险你的时间,这是不值得的。如果你有足够的时间,请继续尝试,这是为你的客户提高账单的好借口。
<强>更新强>
积极的一面。在我的下一个项目中,我将尝试实体框架5.0。感谢上帝,这次我们有源代码:)所以现在看起来并不那么糟糕。
答案 2 :(得分:2)
问题在于这类问题是人们选择框架时存在“宗教”因素,ORM激发了很多激情。
因此存在某些火焰的风险......我个人并不是实体框架的忠实粉丝,我可以看到采用遗留系统和ER模型并将其映射到哪里会很好,但我认为较长期(以及我的用例)更多地围绕域模型设计构建,并且我的实体将映射到该模型。这里有一个很好的blog post,我倾向于同意。
我认为我喜欢像NHibernate和Eco这样的产品。目前我正在尝试使用DB4Objects的真实OODBMS(而不是ORM),到目前为止我印象非常深刻。
答案 3 :(得分:2)
简短回答:等到EF 4.0
答案很长:
我现在正在完成一个中型EF 1.0项目(也是ASP.NET MVC)。我也有NHibernate的经验。除了常见的CRUD映射之外,我们还进行了相当多的继承建模。总的来说,我对它的感受好坏参半。
一些观察结果:
关于EF 1.0,我能说的最好的事情是它具有出色的LINQ集成。它比Linq更适合NHibernate(在其当前版本中)。
EF可以很好地处理有趣的继承映射,但是你会发现很多映射错误,试图让它正确。这里的文档并不是非常有用,并且还没有很多社区支持。你只需要搞清楚。
设计师有缺陷并且不支持EF可以做的所有事情。您经常发现自己手动编辑XML映射文件。设计者在正确的映射xml中创建错误。事实上,我们设计师遇到了很多问题,我们首先要考虑XML,而不是让设计师更新映射。我说这是我对微软产品的一个问题:他们构建的产品面向工具而不是库。在这种情况下,他们匆忙使用工具,因为XML同样糟糕。
XML是,呃,详细。 EF 1.0需要大量的映射信息。对比NHibernate的XML,它只处理映射本身,不需要概念定义或存储定义文件,或者更好的是,像Fluent NHibernate这样的工具,可以让你在代码中指定你的映射。
我个人更喜欢编写本身可以持久化的类(POCO),而不是处理单独的数据实体模型。虽然克雷格关于公共虚拟的观点,但我更喜欢NHibernate的代理方法。我不得不同意克雷格关于EF的意图。我认为他们不打算在EF和业务对象之间创建映射层。作为部分类,意图似乎是您向实体添加行为以创建完整的OO类。考虑到这一点,你不能在没有跳过很多箍的情况下对EF 1.0进行单元测试。
对EF而言,最大的烦恼可能是缺乏透明的延迟加载。真是太糟糕了。
我会等到EF 4.0出来之后才愿意再次使用它。
答案 4 :(得分:1)
我们已经在InterWorks上使用NHibernate 4年了。它对我们很有用,我们在它上面构建了另一层以简化使用(类似于当时我们没有意识到的Castle ActiveRecord)。
NHibernate的缺点是学习曲线,缺乏强大的GUI工具(我们使用自己的MyGeneration模板来生成对象),以及OK社区支持。我们花了很多精力让它为我们工作,并花了很多时间在NHibernate上培训新的团队成员以及围绕它构建的框架。
由于我们主要构建自定义软件,因此我们很难证明重建框架的开销是合理的,但最有可能在未来两年内我们将基于几个非常基本的原因转移到实体框架。 (1)更好的文档和更大的支持社区(它将很快发生)和(2)更容易找到具有EF经验的人,从而消除一些培训成本。
今天的情况并非如此,但是在VS.NET 2010中的EF的下一个版本中,它们将会非常快。它已经非常成熟,并且内置的VS.NET支持很好地实现了它。我们已经用它完成了一些基本测试,但我并没有声称拥有丰富的EF经验。
到MS一段时间才能使用该程序,但现在他们有EF将在这里待很长时间,并将成为标准。如果你没有ORM的经验,我会开始学习EF,从长远来看,这对你的职业生涯会更好。