我应该使用哪个.NET ORM?

16

我相对于.NET比较新,并且已经使用Linq2Sql将近一年,但它缺少我现在正在寻找的一些功能。

我将要开始一个新项目,希望使用以下ORM特性:

  • 非常高效,不想处理访问层从或向数据库保存或检索对象,但应该可以让我很容易地调整任何对象,然后再提交到数据库;并且它应该可以很容易地处理一个变化的数据库架构
  • 允许我扩展从数据库映射的对象,例如为它们添加虚拟属性(表的虚拟列)
  • 至少几乎与数据库无关,应该可以让我以透明的方式使用不同的数据库
  • 没有太多的配置或者基于约定使其工作
  • 可以让我使用Linq

那么,您知道我可以使用的任何ORM吗?谢谢您的帮助。

编辑 我知道一个选项是使用NHibernate。这似乎是企业级应用程序的事实标准,但也似乎不是非常高效,因为它需要深入学习。此外,我在SO上阅读到其他帖子中还说它不能很好地集成Linq。这全都是真的吗?


2
当你要求与MVC集成时,我认为你没有抓住重点。 - Allen Rice
1
这个问题并不主观,我需要的是具体而非随机的东西。 - eKek0
在你编辑时:请查看我在帖子中的回答。Linq得到了100%的支持,如果Fluent提供的足够,陡峭的学习曲线就会完全消失。除了少数情况(奇怪的遗留情况)外,我可以用Fluent做我想做的一切。此外,请参见代码示例以了解它有多“陡峭”(实际上,这几个小时或几天是值得花费的!) - Abel
这个问题中的答案非常接近您所寻找的内容: http://stackoverflow.com/questions/380620/what-object-mapper-solution-would-you-recommend-for-net#380726 - Cohen
@Cohen:我看不出相似之处在哪里。 - eKek0
参见:http://stackoverflow.com/questions/1377236/nhibernate-entity-framework-active-records-or-linq2sql/ - Michael Maddox
9个回答

22
也许你最好使用NHibernate。在商业和开源ORM方面,它可以说是最好的“行业标准”。它已经存在了很长时间以变得非常稳定,被许多企业公司所使用,基于更为著名的Hibernate(Java),但已经完全重写以充分利用.NET功能。
NHibernate的缺点
这听起来像我是NHibernate的支持者。也许我是。但NHibernate有一个缺点:它有一个陡峭的学习曲线,即使对于经验丰富的开发人员来说,熟悉其许多可能性并选择适合您情况的正确或“最佳”实践也可能令人生畏。但这是为了使用几乎可以做到任何事情的企业级ORM而付出的代价。
使用FluentNHibernate的NHibernate效果很棒
许多这些缺点和设置问题在您开始使用Fluent NHibernate后就会消失,个人而言,我几乎再也离不开它了,因为它一下子消除了所有NHibernate的繁琐之处(几乎)。
它使得使用NHibernate变得轻松:只需将您的实体编写为POCO,并自动加载它们以创建您的数据库、关联等(如果已经存在模式,则不创建)。使用流畅的语法配置您的数据库。一个非常简单的设置可以看起来像这样:
// part of a default abstract setup class I use
public ISessionFactory CreateSessionFactory()
{
    return Fluently.Configure()
        .Database(
            MsSqlConfiguration.MsSql2008
                .ConnectionString(c =>
                    c.Server(this.ServerName)
                    .Database(this.DatabaseName)
                    .Username(this.Username)
                    .Password(this.Password)
                    )
        )
        .Mappings(m =>
            m.AutoMappings.Add(AutoMap.AssemblyOf<User>()   // loads all POCOse
                .Where(t => t.Namespace == this.Namespace))
                // here go the associations and constraints,
                // (or you can annotate them, or add them later)
            )
        .ExposeConfiguration(CreateOrUpdateSchema)
        .BuildSessionFactory();
}


// example of an entity
// It _can_ be as simple as this, which generates the schema, the mappings ets
// but you still have the flexibility to expand and to map using more complex
// scenarios. It is not limited to just tables, you can map views, stored procedures
// create triggers, associations, unique keys, constraints etc.
// The Fluent docs help you step by step
public class User
{
    public virtual int Id { get; private set; }   // autogens PK
    public virtual string Name { get; set; }      // augogens Name col
    public virtual byte[] Picture { get; set; }   // autogens Picture BLOB col
    public virtual List<UserSettings> Settings { get; set; }  // autogens to many-to-one
}

public class UserSettings
{
    public virtual int Id { get; private set: }   // PK again
    public virtual int UserId { get; set; }       // autogens FK
    public virtual User { get; set; }             // autogens OO-mapping to User table
}

该框架可以自动映射所有POCO实体,创建ORM的配置并在数据库中构建模式,前提是用户具有足够的权限。Fluent(以及NH到某种程度上)非常强大的一个能力是,在进行任何更改时更新数据库模式。

NHibernate的其他辅助工具

另外一个优点是:许多自动生成工具存在(包括开源MyGeneration),可以从简单的ODBC或其他连接获取DB模式,并将其转换为正确的实体类、关联和HBM配置文件。其中许多工具是(部分)图形化设计辅助工具。

使用S#arp强制执行MVC + NH + NUnit最佳实践

请务必阅读NHibernate最佳实践。它将泛型和DAO带入了下一个级别。您也可以直接使用S#arp下载),这是一个强制执行所有这些最佳实践并将NUnit添加到混合物中的框架。

在开始使用新技术之前,我通常希望它得到很好的覆盖。NHibernate和Hibernate在这方面都不逊色。许多书籍从初学者到专业人士都有解释,白皮书丰富,工具文档也相当出色。

关于LINQ和NH

LINQ和NHibernate一直以来都很好地配合使用,通过各种ICollection<>在多对X映射和其他关联中使用,但需要先检索数据,这需要良好的设计(缓存可以帮助),否则性能会很差。自从LINQ出现以来,这一点一直被视为NH的痛点。

幸运的是,现在有一个新生力量:NHibernate-LINQ,它将LINQ查询映射到提交之前的ICriteria查询上。ICriteria查询具有很好的缓存,并且与LINQ结合使用既强大又高效。 NH-LINQ现在已成为标准发行版的一部分。

免责声明

我已经使用NHibernate将近十年了(首先是Java,后来是.NET)。我曾试过其他商业和开源ORM,但最终总是返回NH(除非公司政策要求不同,但这很少见)。这个故事可能听起来有些偏见,但这里的空间太小,无法详细讨论NHibernate与其他技术的比较。

其他ORM可能更适合您的需求,特别是如果您从未计划在复杂的多数据库、多数据库服务器或难以映射到面向对象的遗留代码情况下使用它。对我而言,NH闪耀是因为它不会在任何方面限制我,并支持完全的往返工程,但如果您需要更轻量级ORM的功能,则您的选择可能会有所不同。

更新:添加了代码示例
更新:扩展了代码示例,修正了拼写错误和措辞
更新:增加章节,添加了LINQ部分,添加了免责声明部分


1
它将关联映射到列表(或任何其他可枚举的对象),这是我使用的方式。但是,使用Linq To NHibernate被认为更好,它将LINQ转换为ICriteria查询(面向对象可编程的NH API,可映射到任何SQL方言)。 ICriteria可能有点难度,这是一个出色的库,可以使它变得更容易:http://www.hookedonlinq.com/LINQToNHibernate.ashx - Abel
1
抱歉,LINQ 错误了,应该是链接问题。Nhibernate Linq 现在已经成为 Nhibernate 的一部分,可以查看 Ayende 的这篇文章:http://ayende.com/Blog/archive/2009/07/26/nhibernate-linq-1.0-released.aspx - Abel
PS:关于您上面的观点:它是100%与数据库无关的(直到您注入特定于DB的查询),被认为非常高效(尤其是使用Fluent和LinqNH),经过一些练习,您可以在10分钟内获得全新的db + schema + dao + dal,可以“基于约定”(再次使用FluentNH),是完全可扩展的(唯一的规定是:需要映射到DB表列的属性必须是虚拟属性或字段,但它们可以是公共或私有的)。 - Abel
我稍微扩展了一下代码,以说明设置这个有多么简单。;-) - Abel
关于Fluent,当您使用Fluent NHibernate时,您将配置放入代码中。这意味着您失去了在部署环境中动态更改nhibernate映射以适应DBA更改的能力。使用Fluent,您必须重新编译和重新部署。流畅的接口非常好用,但在某些情况下,例如NHibernate和IoC容器,它们会削弱这些工具最大的优势之一。 - jrista
显示剩余3条评论

4

为什么不看看subsonic呢?我喜欢它胜过其他的ORM框架,因为它轻量级且能透明地映射到数据库方案(使用ActiveRecord),并且满足您的所有要求。

它必须非常高效。

我认为这是每个ORM框架的工作?使用subsonic,您可以使用控制器(用于数据绑定)或仅在任何ORM对象上执行Save方法。

它应该允许我扩展对象

扩展生成的类很容易,它们都定义为部分类。您甚至可以编辑模板。(它们是您在项目中包含的T4模板,因此您完全控制生成方式和内容)

它必须(至少几乎)与数据库无关

我认为这对于任何ORM框架来说都是基本的。Subsonic支持许多数据库,其中众所周知的是:Oracle、mySql、MsSql、SqlLite、SqlCE。您可以在这里查看数据库支持列表。

它必须没有太多配置或基于约定

是的,绝对是约定优于配置或者他们所说的有主见。关于这些约定的概述可以在这里找到。

它应该允许我使用Linq

自3.0版本以来,完全支持Linq。

关于nhibernate、LinqToSql和subsonic之间的比较,请阅读这篇文章。它是一个公正且最新的比较,并明确概述了不同ORM的愿景差异。

我在subsonic中想要的功能:

  • UnitOfWork支持(您可以通过使用事务支持来解决此问题。)

  • IdentityMap支持(您的对象在某些范围内进行缓存(appdomain、threat、web请求上下文、页面生命周期等)。虽然您可以争论这是否应该是ORM的一部分,还是某个缓存层的一部分。)

我听说Hibernate支持两者。


并非所有ORM都是高效的和数据库无关的。当数据库模式发生变化或者您想要忘记自己从数据库中保存或检索数据时,Linq2Sql非常低效。此外,Linq2Sql仅适用于Sql Server,因此它根本不是数据库无关的。 - eKek0
关于“公平比较”:作者本人说:“我从未使用过NHibernate”,比较本身在subsonic.com上进行,这很难被认为是“公平”的起点(我并不是说它不公平,我只是说看起来不同)。 - Abel
@Abel,实际上这样承认是相当公平的,在我看来。我明确提到“公平”的原因是,当我读到“x的作者与y、z进行比较时……”时,我几乎从不去阅读它。大多数情况下,他们只是强调自己的产品。但这次比较并非如此。他比较了不同ORM的基本差异,这对于新手来说尤其有帮助。 - Cohen

3

它如何与linq集成? - eKek0
1
请查看NHibernate.Linq项目(以及NHibernate家族的其他成员):http://www.nhforge.org。 - Jeffrey Cameron

3
根据您的要求,我建议查看Mindscape LightSpeed。它支持大约八到九个不同的数据库,并且是基于约定的(具有配置选项),因此非常易于设置。它具有LINQ提供程序。它允许您使用自己的属性和方法扩展类:特别是它允许您在不破坏约定优于配置方法的情况下将持久模型(字段)与API(属性和方法)解耦。

1
我对LightSpeed印象非常深刻。它比NHibernate让事情变得更容易。 - Reed Copsey
如果它是基于约定的,我很想看看它与FluentNHibernate相比如何。FluentNHibernate也是基于约定的。 - Abel
1
Abel:啊,抱歉,我对Fluent NHibernate不太熟悉,无法进行比较。从你的代码示例来看,LightSpeed基本上是自动执行FNH AutoMap的等效操作,并使用属性或策略对象指定约定覆盖(我相信FNH使用表达式来实现这一点;是这样吗?)。如果您有兴趣了解更多信息并可能撰写比我的更全面的比较,请使用免费版的LightSpeed! - itowlson
FluentNH使用“约定”来实现这一点,它描述了其应该如何行为。它们可以全局应用,也可以针对每个表、每个字段或每种数据类型进行应用。这里有改进的空间,可以有更多预定义的行为,或者应该更容易地覆盖给定的行为(目前需要一个完整的新继承类,这是灵活的,但不是最简单的,如果我没记错的话)。 - Abel

3

我曾在几个项目中使用过Entity Framework,并且非常喜欢它。首个版本确实存在一些问题,尤其是外键和存储过程处理方式方面,但第二版已经进入测试阶段并内置于VS 2010中,看起来非常有前途。


哈哈哈。说真的,我建议看看真正的企业级ORM - Entity Framework缺少的功能比这里所有答案加起来的还要多。 - TomTom

1

1
与此同时,这已成为标准发行版的一部分。 - Abel

1

哥们,我会选择 Entity Framework。它支持 Linq。Entity Framework 4.0 相比于 3.5 有着重大的性能提升。它拥有你在帖子中需要的一切。EF 不仅仅是一个 ORM 工具,而是一个框架。相比于 M$ 的 Entity Framework,我认为 NHibernate 简直就是个玩笑。NHibernate 没有包含智能感知功能并且安装过程也没那么简单。

许多企业组织也已经采用了 Entity Framework。Entity Framework 可以支持任何可在 Windows 上运行的数据库,因为它有一个特性允许任何供应商为其创建提供程序。做个明智的决定,选择 EF。


3
有趣,为什么NHibernate没有智能提示?NH完全是.NET的,就像其他任何.NET库一样,智能提示也支持NH。安装可以通过图形界面完成,并且XML HBM文件也支持智能提示。但这并不是您应该基于此做出决策的关键因素。 - Abel
-1 - 说真的,基本功能方面,nhibernate 比 entity framework 好太多了。生成的 SQL 更好,它还具有二级缓存能力。Entity Framework 仍然是一个三流的 ORM——至少在 2010 年现在可用。 - TomTom
感谢您解释您的负投票。这篇文章有点旧了,它并不反映我对旧版实体框架的看法。 - Luke101

0
你也可以看看LLBLGen,虽然它没有一个响亮的名字,但它确实具备了你所提到的所有功能:
它支持大多数数据库版本的驱动程序,包括Oracle和SQL等。
它支持Linq,即你可以使用Linq查询LLBLgen生成的对象。
它允许你扩展生成的对象,它们都是部分类。

0

我知道这个问题已经有近8年的历史了,但是至少如果还有人对这个问题感兴趣,他们将会得到更全面的ORMs信息。

我们一直在使用Dapper进行数据库访问。它非常轻量级,极其快速。我仍然可以编写SQL(这是我的首选)。它会自动将返回的数据映射到对象中,甚至是动态对象。您可以添加扩展程序,无需SQL即可插入、更新等操作。因此,您可以将其构建成更接近完整ORM的形式。

一旦您开始使用它,您会惊讶于没有它您是如何生活的。它应该随.NET框架一起发布。

它是数据库不可知的,但是您编写的SQL可能不是。因此,如果您正在编写自己的SQL,您必须确保它适用于目标数据库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接