实体框架成功案例?

10 nhibernate orm entity-framework

就像我之前的许多开发人员一样,我正处于选择ORM进行彻底学习和未来项目前进的十字路口.我一直在玩Entity Framework,到目前为止,就像我看到的那样,虽然我只尝试了简单的东西,CRUD与明确定义的表关系和1-1表实体映射.我在实体框架上做了一些谷歌搜索并发现了大多数负面反馈......我最关心的是映射xml和生成的对象类的复杂性......以及它们依赖于EF的组件类和因此,在涉及对象模型设计考虑因素时需要得到尊重.到目前为止,我倾向于NHibernate ......因为映射文件的相对简单性以及它可以与我制作的POCO对象一起工作以满足我的对象模型设计需求.甚至还有一个LINQ提供商,以及第三方代码生成工具.但是......我不想把EF抛到窗外.有谁知道用EF编写的成功的制作应用程序?或者在技术方面,我现在想要倾向于EF的任何理由,例如拥有企业支持,是新的,因此随着时间的推移,NH已达到成熟的均衡,因此更有可能在功能集中增长?我并不是要在这里开始色彩战争,我只是在寻找人们在做出决定之前可能需要添加的关于EF的积极的事情.

谢谢!

Cra*_*ntz 14

虽然我倾向于同意蒂姆关于框架选择的"宗教"因素,但我仍然觉得有点奇怪,因为很多人都愿意评论EF,因为他们显然没有费心去学习它是如何运作的.事实证明,EF将是一个糟糕的NHibernate版本,就像锤子制作糟糕的螺丝刀一样.按照自己的条件理解EF非常重要.

在我解决这里评论中提出的一些观点之前,我将补充一点,我们刚刚发布了生产Web应用程序的第2版,其中包含0行SQL和100%通过EF或ASP.NET完成的所有数据库访问我们的客户的会员API.我在这里讲的是使用EF的真实经验,令人遗憾的是,对于迄今为止我所看到的关于EF的大多数评论的作者来说,这显然是不正确的.

一般来说,我认为扩展您的实体类型是错误的.蒂姆引用的博客文章的作者(1)并不知道这是可能的,并且(2)认为这是实施DDD的途径告诉我所有我需要知道的关于他的真实世界EF体验:他没有有什么.

POCO支持对于某些ORM的用户来说变得非常重要,因为他们多年来没有实现LINQ功能.由于您基本上坚持使用黑盒子中出现的任何类型对象,因此控制父类型变得非常重要.事实上,如此大,那与所有宣布的成员一起写"POCO" public virtual开始被视为没什么大不了的.在哪个星球上这是一个"普通"类型?它是代理基础,而不是POCO.所谓的"POCO"根本不是POCO.只是他们更喜欢在封装和性能上而不是父类型上妥协.它可能是在他们的工具集的限制范围内的合法妥协,但没有什么可以自大的.

但EF的工作方式不同; 通过LINQ投影作为实际映射的类型,可以很容易地实现任意类型.如果您正在构建通过线路发送对象而不是在内部使用的东西,并且必须具有不依赖于EF的客户端,那么您可以使用RIA服务或编写ADO.NET数据服务.所有的辛勤工作都将为您完成.EF是一系列工具的基础,用于处理将数据库中的数据投影到各种类型的客户端上的问题,而不是单个独立工具,它试图在一个胖框架内处理应用程序内部可能需要的每个单一数据转换.让EF处理从RDBMS到对象空间的投影.然后,您可以使用LINQ to Entities投影到持久性无知类型,或者使用RIA服务投影到Silverlight友好的有线格式.要求一个工具处理任何应用程序可能需要的每个投影,就是乞求用这个工具卡在贫民窟中.

EF基于"价值对象"的概念.这些是具有属性但没有行为的类型.事实证明,值对象对于某些特定问题非常有效,例如通过线路发送数据或坐在RDBMS和OO编程之间的"无人区域".在这里理解关注的分离很重要:实体类型的关键是将RDB 数据放入对象空间.然后,您可以编写实现应用程序的业务类型,并将实体类型投影到业务类型上.然后,您可以自由地实现业务类型,而不会对持久性做出妥协.您可以在需要时更改RDB架构.您只需要更改实体映射和BO投影,而不是BO本身.


Tri*_*Gao 5

由于以下原因,我摆脱了 Entity Framework 4.1 并且再也没有使用过它:

  • 官方文档很烂。几乎没有关于事情如何以及为什么会这样运作的信息。除了基本的 CUD 场景之外,没有任何示例。例如,我有 5 个相关表,并且一个原子操作(一个事务)应该从其中的 2 个中删除记录,然后将一个记录添加到第 3 个,然后使用刚刚的 ID 更新最后 2 个添加。我可以清楚地看到这样做需要什么 SQL。现在在实体框架中,数据上下文上的哪些操作序列可以让我得到相同的结果是一个谜。

有一些很好的文章和爱好者的博客,他们内外都知道,但是嘿,这与在参考资料中查找不同,为什么我希望有人比官方来源的官方文档更了解它?为什么微软不费心为其旗手数据访问技术提供一本更好的手册,其中涵盖了超越一年级书籍示例的操作方法?缺乏有关如何使用它的信息使学习曲线更加陡峭,从而导致浪费时间和错过最后期限。

  • 没有办法进入它内部,看看它在做什么。这是一个精心打造的黑匣子。尽管提倡使用 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。感谢上帝,这次我们有了源代码 :) 所以现在看起来还不错。