不信任的entity framework表决 – 与.NET 4相关?

我正在决定一个大项目的ORM,并决定采用ADO.NETentity framework,尤其是在.NET 4中提供的新版本。在我searchEF的信息期间,我偶然发现了ADO .NET Entity Framework Vote没有信心 ,我不知道如何采取。

不信任投票是在2008年某个时候写的,目的是说服微软倾听EF v1的具体批评意见。

目前尚不清楚“不信任表决”中的声明是否仍然有效(在.NET 4中),以及是否足够认真地使用其他解决scheme。 NHibernate是一个成熟的select,但我不知道它带来了什么问题。 我通常更倾向于Ms解决scheme,主要是因为我可以指望与VS集成和开发人员的支持。

如果不信任投票中提到的问题如何影响现实世界的项目,我将不胜感激。 更重要的是,在.NET 4中,这些声明还是与EF相关吗?

我一直觉得,“不信任投票”的基础是尝试使用EF,就好像它是一个NHibernate的克隆。 这不是,甚至在EF 4尝试使用EF,就好像它是一个NHibernate的假冒可能会以失败告终,尽pipe在失败之前你可能会进一步。 作为一个简单的例子,大多数人在最小的基础上使用NHibernate中的LINQ,尽pipe如此,我认为除非使用LINQ,否则我认为在EF 根本没有生产力。

另一方面,在使用EF 1的时候,我一直很成功,并且设法不允许人们在博客文章中提出要求来阻止我为自己工作。 我期待在EF 4中使用许多新function,但是我很乐意随时为EF 1项目打造良好的结构。 (对于这个问题,我也很高兴和NHibernate一起工作,不会批评它不像EF那样)。

所以我试图用一种微妙的方式来build议,在你决定“不信任表决中的声明是否仍然有效(在.NET 4中)”之前,你必须首先决定这些声明对你和工作的方式永远有效。 如果您对O / R的个人理解是硬连接到NHibernate,那么EF 4对您来说似乎仍然是二stream的。 另一方面,如果你愿意学习EF的工作方式,那EF1甚至可能比你听到的要好。

为了直接解决“不信任”的要求,并检查EF 4的实质和变化:

专注于实体的数据方面导致实体实体架构:

这是entity framework的实体数据模型的一个误解。 (或者,如果你愿意的话,意见分歧。)但是无论如何,这是一个function,而不是一个错误。 entity framework是围绕更一般的数据服务案例而devise的,而不仅仅是O / Rbuild模。 将行为放在从数据服务返回的实体上会导致CORBA风格的灾难。 与你所在的ORM不同,在某种程度上,不pipeORM黑盒子里出现什么types,你都需要entity framework模型投影到业务types上。 在这种情况下, 映射的实体types将永远不会实现。

这是entity framework模型和许多其他ORM之间的实质性区别。 就我个人而言,我发现从O / R映射中分离出商业行为比把它们合并在一起要清楚得多。 你不必同意这个想法,但这显然是一个devise决定,而不是一个疏忽。

过量的代码需要处理,没有懒惰的负载:

EF 4,无论好坏,都有延迟加载。

我说“好或坏”,因为懒加载使生成多余的数据库查询非常容易。 只要你密切关注发生了什么,但是大多数人不这么做。 我发现投影是延迟加载,急切加载或大部分时间的显式加载的更好select。

不过,有时候懒加载是方便的。 所以我很高兴看到它在EF 4中join。

共享,典型模型对抗软件最佳实践:

很难知道该怎么做,因为一些辅助文本甚至不是连贯的英文,例如:

由于缺乏entity framework的精心制作工具,故障倾向典型模型方法并不困难。

这一部分似乎表明,entity framework对于使用复杂系统的单一规范数据模型提出了某种要求,或者至less有强烈的偏见。 我不确定我是否同意,但很难说,因为本节没有任何具体的例子。 所以我会告诉你我自己对这个问题的偏见,你可以同意或不同意我:

对于大型系统使用单一模型通常是一个错误,取决于系统实际的大小。 但是,entity framework中没有任何内容要求您使用单个模型。 另一方面,entity framework,特别是在版本1中,并没有使它容易组合多个模型。

现在,复杂系统的单个大型应用程序与单个大型数据模型一样可能是一个大错误。 因此,entity framework将很多微型模型合并成一个过于庞大的应用程序是不正确的; 那会简单地用另一个replace一个问题。

另一方面,我认为这样做是有道理的,可以很容易地build立一个适合问题领域的方式来划分服务的大型系统。 我认为WCF数据服务是一种独立于entity framework的技术,但它支持entity framework非常有用。

我认为entity framework可以在未来的某个版本中,在需要时将两个或三个模型合并到一个应用程序中。 你现在可以做到这一点,但是有一些手动的工作。 但正如我上面所说,我不想通过促进/鼓励创build一个过大的应用程序来“修复”一个过大的数据模型的问题。

缺乏持久性忽视导致业务逻辑难以阅读,写入和修改,从而导致开发和维护成本增加,

本节提出我认为是错误的要求:

entity framework通过阻止实体类中包含业务逻辑来鼓励贫血域模型反模式。

往上看。 我认为实体types的工作是在对象空间中的关系空间之间进行映射。 按照单一责任原则,这些types只需要在其唯一的工作变化时进行修改。 如果业务stream程发生变化,那么这是一个与O / R映射无关的责任。 其他ORM的限制也许是分离这些责任的技术障碍。 如果devise纯度的成本过高,那么在技术规定时就可以弯曲规则。 但我强烈支持无行为的实体types的方法。

在当前状态下,EF实体类不能独立于数据库进行有效的unit testing。

这是错的 。 谁写这个不明白他们在说什么。 我们的unit testing都不涉及数据库,而且很多都涉及EF。

就本节标题的内容而言,EF 4有所改变。现在可以有完全的持久​​性 – 无知的实体types,如果这有助于你的devise的话。 但是,从entity framework最早版本的文字中,您已经能够投影到POCO上。 所以在需要的时候,持续的无知一直是可用的。 持久性对实体types本身的无知允许对持久性无关的对象进行更改跟踪。 这在某些情况下可能有用。 但是,这个案例比unit testing的虚假要求要less得多,这减less了文档的重要性。

在团队环境中过量的合并冲突与源头控制:

合并XML实际上很难吗? 如果是这样,也许应该看看一个新的合并工具。 我不觉得这个问题。

然而,这里有一个真正的问题,虽然它比文件声明要窄得多。 而不是重复自己,我只是指出你在这个问题上的职位 。

在EF 4中,可以使用代码优先模型而不是XML模型来将模型分成许多不同的文件。

entity framework已经从版本1改进了,这个NHibernate贡献者的博客文章比较了NHibernate和Entity Framework 4.0。

编辑:这被用来是真实的,但它不是任何。

作为一个使用entity framework和NHibernate的人…我强烈build议NHibernate。 通常如果有FOSS和MS技术,我build议MS技术,但是我强烈反对EF。 我在工作中每天使用EF4,而且由于EF,我们必须创build很多解决方法。 两年前,我用EF约一年,然后换了公司,过去一年我一直在EF工作。 NHibernate在2年前已经领先于EF4。

这是他们提出的要点。

团队环境中源代码pipe理的过度合并冲突:

从我听到的情况来看,这部分是固定的。 他们把devise师的位置数据移到了.edmx的底部,所以它不再是一个可怕的问题,但仍然很烦人。 如果我和同事都尝试同时修改.edmx,我们往往会遇到可怕的合并冲突,因为整个文件的底部用于存储devise器中表的位置数据。 我们对这个问题的解决方法是使用SVN文件locking,所以我们不要对其进行双重编辑。 或者我忽略locking,如果我遇到合并冲突,我只是接受他们的变化,并重做我的工作。 我的大部分变化都不是很大,他们需要很长时间才能完成。 如果这是唯一的问题,我会和它一起生活。

如果您使用代码优先(在EF 4.1),这是一个没有问题。

需要过多的代码来处理缺乏延迟加载:

他们在4.0中添加了延迟加载。

但它仍然装载像一个垃圾的预制件。 急切加载速度很慢,当您需要加速代码时,这是一种常见的优化。 我遇到了一些情况,当我宁愿使用急切的加载时,我必须对数据库进行10k +调用。 我们已经计时了,在很多情况下,多次调用数据库myobject.TablenameReference.Load()在循环中执行myobject.TablenameReference.Load() )到本地数据库的速度更快,然后使用.Include("Tablename") 。 是的,我知道这是非常反直觉的,但数字不是谎言。 而且,没有办法指定提取层次,所以你不能指定Join-fetch。 所以我会说这是改进的,但不如NHibernate好。

过分关注实体的数据方面会导致实体体系退化:

是的,这仍然是事实。 状态再次是一个很好的例子。 我们真的希望这是一个枚举,但由于EF的devise方式,除了string之外别无select。 他们可能会在将来修正枚举问题,但是如何在表和对象之间进行映射是真正的抱怨。 NHibernate允许你指定做映射的方法来处理这种情况。

为了从Craig Stuntz的回应中扩展出一个观点,EF的devise围绕着如果你想采取数据模型,并直接从中select。 (IE myModel.Orders.Where(order => order.Status == "NEW").Select(order => order.Customer.FirstName, order=> order.Customer.LastName) 。)EF的模型最终变得很难编写自动化testing,如果你不想击中数据库。 如果你想要一个仓库,你需要一个符合条件的对象,然后它返回整个对象,这就是NHibernate更好的工作。 (IE var order = myOrderRepository.GetByStatus(OrderStatus.New) )。

我与EF有关的另一个问题是完全缺乏可扩展性。 我们遇到的一个问题是我们有订单状态的枚举。 但是,如果我们执行myModel.Orders.Where(order => order.Status == OrderStatus.New.ToString()) ,那么EF将在该查询上崩溃,因为它不知道.ToString()方法。 它使我们的代码变得很糟糕,因为我们不能添加对它的支持。 也有很多内部的方法,所以我们需要引起一个奇怪的行为发生,我们不能这样做。

如果你使用的是NHibernate,Linq增加了很多nhibernatefunction,使它更好。 使用基于约定的模型,大部分映射只需要很less的代码。 如果您使用的是现有的数据库,Nhibernate允许您指定要使用的非标准约定,然后将它们映射到一起,并且一切都可以轻松pipe理。 EF 4.0(我不认为4.1)不支持这样的事情。

我希望这能够帮到你。