用 LINQ to SQL 或 LINQ to EF 替换 NHibernate
Posted
技术标签:
【中文标题】用 LINQ to SQL 或 LINQ to EF 替换 NHibernate【英文标题】:Replacing NHibernate with LINQ to SQL or LINQ to EF 【发布时间】:2010-04-08 12:59:33 【问题描述】:我们有一个很棒的项目,它使用 NHibernate 作为 ORM。我们想迁移到 L2S 或 L2EF。我们可以做我们通过 NHibernate 做的所有事情吗?
你建议我们做这项工作吗?这项工作的优点和缺点是什么? 这两个 ORM 是否有共同的能力?
注意:我们的项目是用 C# 编写的。
【问题讨论】:
Can we do everything that we do by NHibernate?
- 你在 NHibernate 中做什么?
为什么要更改您的 ORM?您在使用 NHibernate 时遇到具体问题吗?
@Darin Dimitrov:我做了 ORM 能做的所有事情。
@Richard Ev:新的公司政策。
您使用的是什么数据库?如果您使用的是 Oracle,L2EF 没有开箱即用的支持,您将需要 3rd 方提供商......加上不支持完整的功能。当然,L2S 不能与 Oracle 一起工作...... :)
【参考方案1】:
您是否有令人信服的理由来更改您的 ORM?我认为不要更改任何内容,因为您有一个现有的应用程序,该应用程序使用良好支持的良好持久性框架运行良好。
是的,您将能够使用 NHibernate 和实体框架做任何您目前正在做的事情(虽然不太确定 LINQ to SQL),但不要为了框架而切换。这就像在您购买汽车一周后更换轮胎一样 - 拥有新的闪亮轮胎可能会令人兴奋,但归根结底,它们只是轮胎。您现在拥有的轮胎很好 - 也许应用程序的其他领域会更好地受益于您为该项目分配的时间?
【讨论】:
同意。据我所知,Linq to sql 和 Linq to EF 甚至都不是 ORM 的。它们实际上是 NHibernate 的相当原始的替代品。 @Stefan:Linq to SQL 不是真正的 ORM,也不打算成为。 Entity Framework 4 肯定是。两者都不是“原始的”——它们是为特定目的而设计的,作为推论,NHibernate Linq 和 EF4 目前在编写复杂的即席查询的能力方面都无法与 L2S 相提并论。与其他一切一样,您需要为工作选择正确的工具。 Entity Framework,即使是在 V4 中,即使有额外的下载,目前在功能上也无法与 NHibernate 媲美。 @Michael:如果 NHibernate 和 EF4 具有完全相同的功能集,那么两者都没有理由存在。他们有不同的 功能集,但暗示NHibernate 不知何故“更好”会被认为是***和愚蠢的。让我们坚持这个话题 - 安德鲁写了一个很好的答案,它不需要被一堆轻率的“我的 ORM 比你的更好”的言论污染。 @Aaronaught:我不忠于 ORM。我认为 Andrew 的这句话是错误的:“是的,您将能够使用 NHibernate 和实体框架做任何您目前正在做的事情”,特别是考虑到提出这个问题的人正在使用 .NET 3.5。【参考方案2】:除非你有一个非常好的理由来改变你的 ORM,否则这将大大比它的价值更痛苦。更改 ORM 与更换数据库提供者一样重要。
NHibernate 中将有其他 ORM 工具中不存在的功能(组件立即浮现在脑海中),因此您必须找到解决方法或重新设计类或表结构来弥补这些变化。
你应该做这项工作吗?我建议不要。
【讨论】:
【参考方案3】:如果您要切换,我强烈建议您不要使用 linq to sql,因为未来是 very unclear。至于 NHibernate 和 linq 到实体之间的功能差异,Ayende Rahien 有一些关于差异的博客文章。
-
nhibernate vs. entity framework 4.0
responding to how ef is better
what can ef 4.0 do that nhibernate can't
仅供参考:Ayende 是 NHibernate 团队的贡献者。
关于你的第二个问题。如果不知道 NHibrinate 是如何让你失望的,就很难提议做这项工作。根据产品的状态和大小,如果没有经过深思熟虑的原因,我很难推荐更改应用程序的一个组成部分,例如 ORM。
无论如何,NHibrinate 是一款非常可靠的产品,在 .net 开源社区中有着悠久的记录。另一方面,Microsoft 有引入数据访问/ORM 解决方案并迅速放弃它们的历史。
【讨论】:
我同意你的观点,NHibernate 是一个非常可靠的产品。但是,您说:“另一方面,Microsoft 有引入数据访问/ORM 解决方案并迅速放弃它们的历史。”。对此我不同意。他们“放弃”的唯一数据访问是 LINQ to SQL。 ADO.NET 仍在底层使用,没有理由假设 EF 将被放弃,Object Spaces 从未使其成为 RTM,因此称其为“被放弃”是不公平的。即使使用 LINQ to SQL,我们也可以争论它是否被放弃。 Microsoft 仍在对其进行错误修复,但不要指望新功能。 自从 .net 出现以来,Microsoft 确实有构建数据访问库/ORM 的历史,并且没有在它们的基础上构建它们,而是推出了一些新的东西。有效地放弃了以前的解决方案。这是我对 MS .net 数据访问演变的解释:DataSets -> Typed Datasets -> Data Access Block -> Enterprise library -> Linq to Sql -> Linq to entity。 Linq to entity 可能是一个长期的解决方案,但微软的历史并没有让我相信。 @Steven:甚至在 ADO.NET 出现之前,Microsoft 就出现了一系列不断变化的数据访问内容:ODBC、DAO、RDO、ISAM、Jet、ADO。其中一些仍然以一种或另一种方式存在。从许多方面来看,ADO.NET 似乎是寿命最长的一个。老实说,我不知道微软是否有耐心坚持使用实体框架,或者他们是否会转向不同的东西。【参考方案4】:Linq to SQL 确实不支持 NHibernate 的整个功能集附近的任何地方。我使用 Linq to SQL 并认为它很棒,但它旨在用作与数据库的直接 1:1 映射。与 NHibernate 相比,它不是真正的 ORM,而是更多的数据访问解决方案。除其他外,它丢失了:
组件属性; 多对多映射; 自动映射(尽管设计器工具主要弥补了这一点); 多平台支持(Linq to SQL 仅真正支持 SQL Server 和 SQL CE) 将多个表映射到一个类中Entity Framework 4 在功能集方面非常接近 NHibernate,您应该能够完成目前在 NHibernate 中能够完成的大部分工作。但我完全同意其他人的建议,不要仅仅为了好玩而改变你的 ORM;实际语义非常不同,您最终会经历很多痛苦和错误修复周期。
【讨论】:
【参考方案5】:您想要迁移的原因是什么?现有的解决方案不起作用吗?是性能问题吗?我建议花一点时间确保您了解问题是什么,性能或其他方面,并专注于这些。使用数据库上的正确索引并使用批处理等 NHibernate 功能,您可能会发现您的问题无需重写即可解决。
另外,将 LinqToNHibernate 视为第一步。 Linq 语法将与您最终使用的语法相同。这就是 Linq 的魅力所在。
【讨论】:
【参考方案6】:NHibernate 允许您在不一直调用 DAL 的情况下实现您的逻辑(“persistence ignorance”)。这是可能的,因为 NH 会比较内存中的实例并自动检测更改。
它具有出色的性能特性(例如缓存、查询批处理、插入/更新批处理、延迟加载)。
当以正确的方式使用 NHibernate 时,您编写应用程序时就好像没有任何持久性(比如说:达到 80%)并且仍然可以获得高性能。由于 Linq to Sql 或 EF 不提供此功能(AFAIK),我无法想象如何将大型应用程序迁移到该功能。您的代码需要一直调用 DAL,而目前不需要。
【讨论】:
呃……Linq to SQL 和 EF 都具备所有这些特性,主要是通过IQueryable
接口和CompiledQuery
类。唯一缺少的是批量更新/删除,但它很容易实现。
@Aaronaught:那不是真的。例如,两者都没有二级缓存。还有其他示例,特别是如果您无需额外下载即可将它们开箱即用。
@Michael:当然,但是这个答案没有提到二级缓存。我只是回应他列出的事情。 Linq to SQL 和 EF 都具有:持久性无知、缓存查询、查询批处理和延迟加载。
我的意思是:“自动”批处理,而不是批量查询的能力。我的意思是一般的缓存(第一级,第二级,查询缓存)。我的意思是所有这些完全不会影响您的代码的好功能。 (除了这些东西在您的代码中缺少。)
@Aaronaught:我对 Stefan 的回答的解读与您的不同。 EF 3.5 没有基于代理的延迟加载(我想您可能会争论 EF 3.5 提供支持的延迟加载的一些定义,但这是相当牵强的)。我不知道开箱即用的 LinqToSql 或 EF 3.5 支持持久性无知,这对我来说是个新闻——也许我对这个术语的理解与你的不同。我确实相信 EF 4 支持延迟加载和持久性无知。以上是关于用 LINQ to SQL 或 LINQ to EF 替换 NHibernate的主要内容,如果未能解决你的问题,请参考以下文章