我正在为一个大型项目决定一个ORM,并决定选择ADO.NET实体框架,特别是它随.NET 4提供的新版本。在我搜索有关EF的信息时,我偶然发现了{{3我不知道该怎么做。
在2008年的某个时候写下了“不信任投票”,以说服微软听取对EF v1的具体批评。
目前尚不清楚在“不信任投票”中提出的声明是否仍然有效(在.NET 4中)以及它们是否足够严重以至于使用其他解决方案。 NHibernate是一个成熟的选择,但我不知道它带来了什么问题。我通常更倾向于使用Ms解决方案,主要是因为我可以指望与VS的集成以及他们的开发人员支持。
我希望示例,了解“无信任投票”中提到的问题如何影响现实世界的项目。 更重要的是,在.NET for .NET 4中提出的声明是否仍然相关?
答案 0 :(得分:64)
答案 1 :(得分:8)
实体框架自版本1以来有所改进,而来自NHibernate贡献者的blog post比较了NHibernate和Entity Framework 4.0。
答案 2 :(得分:5)
编辑:这是真的,但不是任何时候。
作为一个使用过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)不支持任何类似的东西。
我希望这可以帮助你。
答案 3 :(得分:0)