NHibernate与LINQ to SQL

NHibernate与LINQ to SQL

NHibernate vs LINQ to SQL

作为没有在现实世界项目中使用这两种技术的人,我想知道是否有人知道这两者是如何互补的以及它们的功能有多少重叠?


LINQ to SQL强制您使用每类表模式。使用此模式的好处在于,它实现起来快速简便,并且只需花费很少的精力就可以在现有数据库结构的基础上运行域。对于简单的应用程序,这是完全可以接受的(并且有时甚至更可取),但是对于更复杂的应用程序,开发人员通常会建议改用域驱动的设计模式(这是NHibernate所促进的)。

每类表模式的问题在于数据库结构对域设计具有直接影响。例如,假设您有一个"客户"表,其中包含以下列来保存客户的主要地址信息的列:

  • 街道地址
  • 压缩

现在,假设您也要为客户的邮寄地址添加列,以便在"客户"表中添加以下列:

  • MailingStreetAddress
  • 邮寄城市
  • 邮件状态
  • 邮递区号

使用LINQ to SQL,您域中的Customer对象现在将具有这八个列中每个列的属性。但是,如果您遵循域驱动的设计模式,则可能已经创建了一个Address类,并且让Customer类拥有两个Address属性,一个属性用于邮件地址,另一个属性用于其当前地址。

这是一个简单的示例,但它演示了"按表创建表"模式如何导致一个有点臭的域。最后,取决于您。同样,对于只需要基本CRUD(创建,读取,更新,删除)功能的简单应用程序而言,LINQ to SQL由于其简单性而非常理想。但是我个人喜欢使用NHibernate,因为它可以简化域。

编辑:@lomaxx-是的,我使用的示例过于简单,可以进行优化以与LINQ to SQL一起很好地工作。我想让它尽可能地基本,以便使观点正确。关键是,尽管在某些情况下,让数据库结构确定域结构是一个坏主意,或者至少会导致次优OO设计。


到目前为止,遗漏了两点:

  • LINQ to SQL不适用于Oracle
    或除SqlServer之外的任何数据库。但是,第三方确实为Oracle提供了更好的支持,例如devArt的dotConnect,DbLinq,Mindscape的LightSpeed和ALinq。 (我对此没有任何个人经验)

  • Linq to NHibernate让您使用
    Linq与Nhiberate,所以它可能
    删除不使用的原因。

而且,Nhibernate的新流利界面似乎使配置Nhibernate的映射变得不那么麻烦。 (消除了Nhibernate的痛苦之一)

更新资料

Linq to Nhiberate在现在处于Alpha状态的Nhiberate v3中更好。看来Nhiberate v3可能会在今年年底推出。

从.net 4开始,实体框架工作也开始看起来像是一个真正的选择。


@Kevin:我认为您所展示的示例的问题在于您使用的数据库设计不佳。我以为您会创建一个客户表和一个地址表并对其进行规范化。如果这样做,您可以针对您所建议的方案使用Linq To SQL。 Scott Guthrie在使用Linq To SQL方面有很多文章,我强烈建议您查看。

我认为您不能说Linq和NHibernate相互补充,因为这暗示着它们可以一起使用,尽管这是可能的,但您最好选择一个并坚持下去。

NHibernate允许您以高度灵活的方式将数据库表映射到域对象。它还允许您使用HBL查询数据库。

Linq to SQL还允许您将域对象映射到数据库,但是它使用Linq查询语法来查询数据库

此处的主要区别在于,编译器会在编译时检查Linq查询语法,以确保您的查询有效。

linq需要注意的一点是,它仅在.net 3.x中可用,并且仅在VS2008中受支持。 NHibernate在2.0和3.x以及VS2005中可用。

NHibernate需要注意的一点是,它不会生成您的域对象,也不会生成映射文件。您需要手动执行此操作。 Linq可以
为您自动执行此操作。


Fluent NHibernate可以基于简单约定生成映射文件。无需编写XML且具有强类型。

我最近从事一个项目,出于性能原因,我们需要从Linq更改为SQL到NHibernate。特别是L2S实现对象的方法似乎比NHibernate的同上慢,并且变更管理也很慢。对于不需要的变更,可能很难关闭变更管理。

如果要使用与DataContext断开连接的实体-例如在WCF场景中-您可能会遇到很多麻烦,需要再次将它们连接到DataContext来更新更改。 NHibernate对此没有任何问题。

我会从L2S遗漏的东西主要是代码生成,该代码生成使实体两端的关系保持最新。但是我想NHibernate也有一些工具可以做到这一点...


您能否阐明" LINQ"的含义?

LINQ不是数据访问技术,它只是一种语言功能,支持将查询作为本机构造。它可以查询任何支持特定接口的对象模型(例如IQueryable)。

许多人将LINQ To SQL称为LINQ,但这根本不正确。 Microsoft刚刚发布了带有.NET 3.5 SP1的LINQ To Entities。此外,NHibernate具有LINQ接口,因此您可以使用LINQ和NHibernate来获取数据。


通过LINQ,我假设您是说LINQ to SQL,因为LINQ本身没有与之关联的数据库。它只是一种查询语言,带有大量语法糖,使其看起来像SQL。

在最基本的基本示例中,NHibernate和LINQ to SQL似乎都在解决相同的问题。一旦获得通过,您很快就会意识到NHibernate支持许多功能,这些功能使您可以创建真正丰富的域模型。还有一个LINQ to NHibernate项目,该项目使您可以使用LINQ来查询NHibernate,与使用LINQ to SQL几乎相同。


首先,让我们分开两件事:
数据库建模关注数据,而对象建模关注实体和关系。

Linq-to-SQL的优点是可以从数据库架构中快速生成类,以便可以将它们用作活动记录对象(请参阅活动记录设计模式定义)。

NHibernate的优点是可以在对象建模和数据库建模之间提供灵活性。可以对数据库进行建模,以在考虑性能的情况下最好地反映您的数据。虽然您的对象建模将使用诸如域驱动设计之类的方法来最好地反映业务规则的元素。 (请参阅彭凯文的评论)

对于建模和/或命名约定不佳的旧数据库,Linq-to-SQL会将这种不需要的结构和名称反映给您的类。但是,NHibernate可以用数据映射器隐藏这种混乱情况。

在数据库命名良好且复杂度较低的未开发项目中,Linq-to-SQL可能是不错的选择。

但是,您可以将Fluent NHibernate与自动映射结合使用,以实现相同的目的,并按照惯例进行映射。在这种情况下,您不必担心任何带有XML或C#的数据映射器,并让NHibernate根据您可以自定义的约定从您的实体生成数据库架构。

另一方面,Linq-to-SQL的学习曲线比NHibernate小。


正如您所写的"给一个没有使用过任何一个的人"
LINQ to SQL易于使用,因此任何人都可以轻松使用它
它还支持程序,这在大多数时候都可以提供帮助。
假设您要从多个表中获取数据,然后编写一个过程并将该过程拖到设计器中,它将为您创建所有内容,
假设您的过程名称为" CUSTOMER_ORDER_LINEITEM",该过程将从所有这三个表中获取记录,然后编写

1
2
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();

您也可以在foreach循环中使用记录对象,NHibernate不支持


或者,您可以使用Castle ActiveRecords项目。我已经使用了很短的时间来为遗留项目增加一些新代码。它使用NHibernate并在活动记录模式上工作(给定我知道的名字,这令人惊讶)。我还没有尝试过,但是我假设一旦您使用了它,如果您觉得需要直接获得NHibernate支持的话,那么对您的部分或全部项目这样做就不会太多了。


推荐阅读