我应该使用.net的ORM?

时间:2009-11-07 01:28:08

标签: c# .net orm

我是.NET的新手,已经使用Linq2Sql近一年了,但它缺少我现在正在寻找的一些功能。

我将开始一个新项目,我想在其中使用具有以下特征的ORM:

  • 它必须非常高效,我不想处理访问层以保存或从数据库中检索对象,但它应该允许我在实际将其提交到数据库之前轻松调整任何对象;它也应该允许我使用不断变化的数据库模式轻松工作
  • 它应该允许我扩展从数据库映射的对象,例如向它们添加虚拟属性(虚拟列到表)
  • 它必须(至少几乎)与数据库无关,它应该允许我以透明的方式使用不同的数据库
  • 它必须没有那么多配置,或者必须基于惯例才能使其正常工作
  • 它应该允许我使用Linq

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

编辑我知道选项是使用NHibernate。这似乎是企业级应用程序的事实标准,但由于其深度学习曲线,它似乎也不是很有效。换句话说,我在SO中读到了其他一些帖子,认为它与Linq不能很好地集成。这一切都是真的吗?

9 个答案:

答案 0 :(得分:22)

也许你最好的选择是使用NHibernate。对于商业和开源ORM而言,它可以说是最好的“行业标准”。它已经在很长一段时间内变得非常稳定,在许多企业公司中使用,基于更为人所知的Hibernate(java),但已经完全重写以充分利用.NET功能。

NHibernate的缺点

这听起来像我是NHibernate的拥护者。也许我是。但NHibernate有一个缺点:它有一个陡峭的学习曲线,并习惯了许多可能性,为你的情况选择正确或“最佳”的做法可能是令人生畏的,即使对于有经验的开发人员。但这是支付企业级ORM的奖励,它几乎可以支持任何事情。

NHibernate与FluentNHibernate岩石

这些缺点和设置问题中的许多问题在你开始使用Fluent Nhibernate时就会消失,个人而言,我几乎不再没有它,因为它一下子(几乎)消除了所有繁琐的NHibernate。

它使得使用NHibernate变得轻而易举:只需将您的实体编写为POCO并自动加载它们以创建数据库,关联等(或者如果已经存在则不创建模式)。使用Fluent语法配置数据库。一个非常简单的设置可以看起来像这样基本:

// 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或其他连接中获取数据库模式,并将它们转换为正确的实体类,关联和HBM配置文件。其中许多工具都是(部分)图形设计辅助工具。

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

请务必阅读NHibernate best practices。它将泛型和DAO提升到了一个新的水平。您还可以跳过追逐并深入了解S#arpdownload),这是一个强加所有这些最佳实践的框架,并将NUnit添加到混合物中。

在我开始使用新技术之前,我通常希望它得到很好的覆盖。 NHibernate和Hibernate在这里并不简单。许多书籍解释了(N)Hibernate从入门到专业,白皮书丰富,工具文档同时相当出色。

关于LINQ和NH

LINQ和NHibernate总是通过所有类型的ICollection<>很好地结合在一起,这些ICriteria用于多对X映射和其他关联,但需要先检索数据,这需要一个好的设计(缓存有帮助),否则它会表现不佳。自LINQ问世以来,这一直被认为是NH的痛处。

幸运的是,现在城里有了一个新孩子:NHibernate-LINQ,它在提交之前将LINQ查询映射到{{1}}个查询。 ICriteria查询得到很好的缓存,与LINQ的这种组合非常强大且性能非常高。 NH-LINQ现在是标准发行版的一部分。

声明

我已经使用NHibernate几乎十年了(第一个Java,后来的.NET)。我与其他ORM的商业和开源调情,但最终总是回到NH(除非公司政策要求不同,但这种情况很少见)。这个故事可能听起来有点偏颇,但这里的空间太短,无法详细阐述NHibernate与其他技术的比较。

其他ORM很有可能更适合您的需求,特别是如果您从未计划在复杂的多数据库,多数据库服务器或难以映射到OO的传统情况下使用它。对我来说,NH闪耀,因为它不会限制我任何方式,并支持完整的往返工程,但如果这里讨论的较轻的ORM的特征对你来说重要的话,你的选择可能会变得不同。

更新: 添加了代码示例
更新:扩展代码示例,修复错别字和措辞
更新:小章节,添加了LINQ部分,添加了免责声明部分

答案 1 :(得分:4)

为什么不看subsonic? 我比其他人喜欢它,因为它是对数据库方案透明的轻量级映射(使用ActiveRecord)并满足您的所有要求。

  

必须非常高效。

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

  

它应该允许我扩展对象

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

  

必须(至少是全部)   数据库不可知

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

  

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

是的,它完全是对配置的约定或他们称之为固执己见。有关约定的摘要,请查看here

  

它应该允许我使用Linq

当然,从版本3.0 Linq开始支持。

对于nhibernate,LinqToSql和亚音速读取之间的比较this这实际上是一个公平和最新的比较,并明确概述了不同ORM的视觉差异。

我在亚音速中错过的事情:

  • UnitOfWork支持(你可以解决 这是通过使用支持 交易。)

  • IdentityMap支持 (你的对象被缓存在一些 范围(appdomain,威胁,Web请求 上下文,页面生命周期,...)虽然 如果这应该是好的,那你就好好争辩吧 成为ORM或某些缓存层的一部分。

我听说hibernate都支持。

答案 2 :(得分:3)

我建议查看NHibernate。

https://www.hibernate.org/343.html

答案 3 :(得分:3)

根据您的要求,我建议您查看Mindscape LightSpeed。它支持大约八个或九个不同的数据库,并且是常规驱动的(具有配置选项),因此非常容易设置。它有一个LINQ提供程序。它允许您使用自己的属性和方法扩展类:特别是它允许您将持久模型(字段)与API(属性和方法)分离,而不会违反约定优于配置方法。

答案 4 :(得分:2)

我已经将Entity Framework用于了几个项目并且非常喜欢它。在第一个版本中肯定存在一些问题,特别是它处理外键和存储过程的方式,但是版本2,处于测试阶段并且是VS 2010的一部分看起来很有希望。

答案 5 :(得分:1)

就像这里的一些答案的后续行动一样,NHibernate Linq由令人难以置信的多产的Oren Eini带头,AKA Ayende Rahien

http://ayende.com/Blog/archive/2009/07/26/nhibernate-linq-1.0-released.aspx

没有使用它,但它看起来非常令人印象深刻。似乎在某种程度上它甚至可以替代LINQ for SQL。

答案 6 :(得分:1)

Man ..我会选择实体框架。它支持Linq。实体框架4.0的主要性能改进超过3.5。它包含您在帖子中所需的一切。 EF更像是一个ORM它是一个框架。我认为与M $实体框架相比,nhibernate是一个笑话。 Nhibernate真的放弃了球,因为不包括intellisense并使设置更容易。

许多企业组织也接受了实体框架。实体框架可以支持任何可以在Windows上运行的数据库,因为它具有允许任何供应商为其创建提供程序的功能。帮自己一个忙,和EF一起去。

答案 7 :(得分:0)

您还可以查看LLBLGen虽然它缺少一个活泼的名称,但它确实具有您提到的所有功能:

它是大多数数据库版本,Oracle和SQL等驱动程序 它支持Linq,因为您可以使用Linq查询LLBLgen生成的对象 它允许您扩展生成的对象,它们都是部分类

答案 8 :(得分:0)

我知道这个问题差不多已有8年了,但至少如果这个问题存在争议,他们将会更全面地了解可用的ORM。

我们一直在使用Dapper进行数据库访问。它非常轻巧。它非常快。我仍然可以编写SQL(这是我的偏好)。它会自动将返回的数据映射到对象,甚至是动态对象。您可以添加将插入,更新等的扩展,而无需SQL。因此,您可以构建它以更接近地模拟完整的ORM。

一旦你开始使用它,你会感到震惊,没有它你的生活。它应该随.NET框架一起提供。

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