请推荐用于N层开发的.NET ORM。

10

我需要仔细选择用于N层应用的.NET ORM框架。

这意味着我将拥有一个作为服务器(WCF服务)的部分,它将公开数据,以及一个显示数据的客户端部分。

ORM应该可以平稳地支持所有相关的序列化问题 - 对象或对象集合等任何必须跨进程边界传输的内容。理想情况下,多进程环境中的使用应与单进程中的使用相同。

这里的标准是:

  1. 数据库模式映射到对象的灵活性(首选)
  2. 易用性
  3. 免费、开源(首选)
  4. 必须适用于N层(多进程多域应用程序)
  5. 性能
  6. 与Visual Studio集成的工具(首选)
  7. 可测试性
  8. 采用度、文档可用性
  9. 广泛支持各种关系型数据库(首选;我们正在使用MSSQL,但我不想被其绑定)
  10. DB无关 - 不同的数据库,同一API

http://stackoverflow.com/questions/1377236/nhibernate-entity-framework-active-records-or-linq2sql/1378028#1378028 - Michael Maddox
7个回答

10
  • The Con: Can be slower at runtime due to the overhead of tracking entity state and maintaining associations. Also, heavy-weight ORMs can be more difficult to learn and use for developers who are not familiar with the specific ORM.

  • Light-weight

    • NHibernate, Entity Framework 4.0+, LINQ to SQL, and DataTables all fall into this category. Light-weight ORMs typically do not require a base class inheritance for entities and collections, and often offer less design time support and code generation. However, they still provide runtime features such as change tracking, transactional behavior, and association maintenance.

    • The Pro: Easier to learn and use for developers, and can provide better performance at runtime due to their lighter weight nature.

    • The Con: May require more code upfront to interact with entities at runtime (ie. from NHibernate's session.SaveOrUpdate(entity) or entity.MyField)

  • Ultimately, the choice between a heavy-weight ORM and a light-weight ORM depends on the specific needs of the project and the preferences of the development team.

  • 缺点:过重和依赖性。使用这些 ORM 后,您的业务对象现在直接与 ORM API 相关联。如果您想更改为另一个 ORM,怎么办?还有什么防止初级开发人员滥用 ORM API 的高级功能来解决简单问题(我见过很多这种情况)?这些 ORM 还存在内存使用量大的问题。使用一些上述 ORM 之一,5000+ 实体集合可能会轻松占用 100MB 的内存。序列化是另一个问题。由于对象过重,序列化可能非常慢...并且它可能不会在另一端(WCF 或 .NET 远程调用等)正确反序列化。关联可能最终无法正确重新关联,或某些字段可能无法保留。上述几个 ORM 中有几个内置了序列化机制以提高支持和速度...但没有一个我见过的能够完全支持不同格式(即你可以获得二进制,但不是 json 或 xml 序列化支持)。

  • 轻量级

    • LINQ to SQL、Entity Framework POCO 和 NHibernate(有点)属于这一类别。轻量级 ORM 通常使用 POCO,您可以在 VS 中的文件中自己设计它们(当然,您也可以使用 T4 模板或代码生成器)。

    • 优点:轻量级。保持简单。ORM 无关的业务对象。

    • 缺点:功能较少,如实体图维护、状态跟踪等。

  • 无论选择哪一个 ORM,我的个人偏好是坚持使用 LINQ 和 ORM 独立的检索语法(不是 ORM 自己的获取 API,如果它有的话)。

    关于上述 ORM,以下是我的简要想法: - NHibernate:技术落后。需要大量维护 XML 映射文件(虽然 Fluent NHibernate 可以缓解此问题)。

    • LLBLGen:我使用过的最成熟的ORM。很容易启动新项目并开始使用。拥有最好的设计器。非常臃肿,但API非常强大。速度是我遇到过的最快的。由于它不是新兴技术,一些利用新技术的更新功能实现得不如应该(尤其是LINQ)。

    • Entity Framework:4.0中的POCO类看起来很有前途。3.5没有这个功能,我甚至不考虑使用它。即使在4.0中,它的LINQ支持也不太好,并且生成的SQL较差(对于单个LINQ查询可能会生成数百个数据库查询)。在处理大型项目时,设计器支持较差。

    • LINQ to SQL:拥有极佳的LINQ支持(除了DataObjects.Net以外比其他任何框架都要好)。持久化支持一般(保存/更新)。非常轻量级(POCO)。无论哪方面,设计器支持都很差(无法从数据库刷新)。在高级LINQ查询上性能较差(可能会生成数百个数据库查询)。

    • DataObjects.Net:真正出色的LINQ支持和性能。提供重量级ORM中最接近POCO的东西。这是一项非常新的、强大和有前途的技术。非常灵活。

    • OpenAccess:我没有太多使用它的经验,但它让我想起LLBLGen,但不像LLBLGen那么功能丰富或成熟。

    • DataTables:无评论


    我认为你应该重新分类Entity Framework POCO。正如你所描述的那样,它绝对不是一个“轻量级”框架。即使使用EF v4的POCO,您也可以充分利用EF的全部功能...您不会失去任何东西,但不会遇到像LLBLGen这样的“重量级”框架的麻烦。如果您使用Code-Only,尤其如此。您对EFv4的LINQ和SQL支持的描述也非常不准确...您描述的是EFv1的SQL查询和LINQ支持...EFv4已经得到了根本性的改进。 - jrista
    我强烈不同意我的EF描述有误。上周我尝试了以下操作:1.在投影中包含枚举值。我在示例中看到过这种情况,并且在LINQ to SQL中可以正常工作。但在EF 4.0中,我会得到一个无效的转换异常。2.在主查询的属性上连接的嵌套子查询。虽然LINQ to SQL可以工作,但每个子查询实例都会发出一个查询,因此性能非常差。EF 4.0根本不起作用。会抛出关于嵌套子查询是常量的异常。DataObjects .Net是我见过唯一能够以良好性能执行嵌套子查询场景的ORM。 - Jeff
    @jrista:仅有代码是非常不成熟的。 - Frans Bouma
    我想我同意Frans的观点...我在哪里听过你的名字... :)...但是你能详细说明一下吗? - Jeff
    要在OpenAccess中纠正记录,它还允许基于轻量级POCO模型的开发,并且不需要特定的基类实现。比EF等工具更快、更成熟。绝对值得一看。 - Todd
    显示剩余3条评论

    7

    6
    我建议使用Entity Framework v4。与v1相比,它有了巨大的改进,并支持你所需的一切,除了开源外。
    1. EF支持多种映射方式,包括TPH、TPT和TPC。支持POCO映射,使持久性逻辑与域分离。
    2. EF具有广泛且出色的LINQ支持,提供易于使用、编译时检查的模型查询。EF Futures组件,如Code-Only,更简化了与EF的工作,提供了纯代码、编译时检查的流畅API来定义您的模型。通过选择约定而非配置,Code-Only可以极大地减少您的模型设计时间,让您专注于业务,而无需费心调整视觉模型和多个XML映射文件。
    3. 它是.NET 4的一部分,免费使用。(抱歉,无法满足开源偏好。)
    4. EF通过self-tracking entities提供了一个优秀的N-Tier解决方案。
    • 自我追踪信息使用开放的XML格式传输跟踪数据,因此可以将跟踪支持添加到非.NET平台
    1. EF v4的性能非常好,因为在查询生成器上进行了大量工作
    1. EF提供非常丰富的可视化设计工具,并允许通过自定义T4模板和工作流程广泛定制代码生成。
    2. EF v4引入了许多接口,包括IObjectSet<T>IDbSet<T>接口,极大地提高了自定义上下文的单元测试性。
    3. EF v4是.NET 4的一个组成部分,也是微软当前和未来所有数据计划的核心组件。作为.NET的一部分,其文档相当详尽:MSDN,EFDesign博客ADO.NET博客,数十个.NET和编程网站和博客为平台提供了大量的文档和支持。

    2
    没有一个合适的设计师,EF v4也不是那么容易使用的。你列举的功能通常只能在编辑EDMX文件后实现。我发现你的第6点并不是很令人信服。但是我有偏见,我知道 ;) - Frans Bouma
    2
    @Frans:我猜我应该预料到LLBLGen之王会有所反驳。我已经阅读了你的博客一段时间,虽然我不想这么说,但你经常表现出对EF(以及L2S和LINQ)能力的理解不足。与EF v1的设计带来的灾难不同,EF v4的设计师更加灵活。通过T4模板,生成的代码是高度可定制的。自从转换到v4以来,我从未不得不编辑EDMX...这是v1的常见问题。其次,使用Code-Only,您甚至没有EDMX文件,因此任何可能由于EDMX引起的问题都将被消除。 - jrista
    1
    关于第6点,ADO.NET博客上的以下文章介绍了使用T4模板和Windows Workflow进行自定义生成:http://blogs.msdn.com/b/adonet/archive/2009/11/05/model-first-with-the-entity-framework-4.aspx - jrista
    可能你没有注意到,llblgen pro v3支持EF v4(和v1),而且我编写了所有的支持代码,所以我确实对它非常了解;请参见此视频: http://weblogs.asp.net/fbouma/archive/2010/04/28/llblgen-pro-v3-0-with-entity-framework-v4-0-12m-video.aspxEF v4设计器可能适合你,但我想看看你如何在模型优先的情况下使用100多个表格系统。Code first还远未完成,我不认为这是一个论点。你似乎很喜欢EF,很好,但请保持现实。就这些。 - Frans Bouma

    1

    我也支持使用EF。

    • 非常容易进行单元测试。您可以编写自己的领域实体,并使用POCO方法使它们相对于持久性意识合理地自由。然后,您可以模拟数据库接口并测试应用程序逻辑,而无需实际数据库。

    • 支持LINQ,因此如果您正确编写LINQ,则只会将单个SQL语句发送到服务器。


    1
    我一直在使用一个叫做LightSpeed的产品,它非常好用,并且可以无缝集成到Visual Studio 2010和2008中。我一直在使用它与Sqlite配合使用,但它也支持许多关系型数据库管理系统。它还有一个非常好的功能,可以创建POCO对象,可用于WCF,这是一个很好的时间节省工具!起初我使用的是免费的Express Edition,但很快就升级了。

    LightSpeed是最好的高性能.NET领域建模和O/R映射框架。一流的LINQ支持、Visual Studio 2008和2010设计师集成以及我们著名的高性能核心框架意味着您可以比以往更快、更轻松地创建丰富的领域驱动模型。


    0

    在几个项目中使用OpenAccess后,我必须说它满足了所有上述标准。 我曾经工作的一个系统是基于WCF服务与多个客户端类型(智能、Web、其他WCF服务等)通信。通过层次化架构,WCF服务使用OpenAccess作为持久化机制。 我特别喜欢OpenAccess执行缩放的功能。智能的二级缓存(L2缓存)在这方面表现得非常出色,而且它当然是可分布的。 事实上,我不认为OA是重量级的...你甚至不需要继承基类。此外,集成到Visual Studio的日常开发人员任务工具(创建新的DB模式、合并模式等)也是一个大加分。


    0
    关于EF4...
    请不要在大型项目中使用它,尤其是在有很多表、大量数据和众多用户的情况下。我犯了这个错误,现在正在寻找替代方案。
    1-查询生成效果很差,特别是在大型TPT层次结构中。为一个包含15个表的层次结构生成5000行的查询语句是常态!
    2-随着表数量的增加,设计师的速度变得极其缓慢。在一个拥有240个实体的模型中,折叠/展开一个实体需要45秒的时间。
    3-对于x至多关系存在严重问题。假设你有一个名为"Order"和"Customer"的实体。每个订单都有一个客户,每个客户有很多订单。在"Customer"类中有一个名为"Orders"的属性,该属性将被填充,即使您实际上并不需要这些数据。在我们的系统中,这意味着可能会检索出多达1800000个实体的集合,而实际上没有任何理由。当这发生在快照隔离级别的事务中时...整个系统就会崩溃。目前没有真正解决这个问题的方法,没有严重的副作用。只需阅读DataObjects.Net的文档,看看他们是如何解决这个问题的。我发现支付200或500欧元与所获得的好处相比微不足道。我甚至可以获得带有源代码的版本。
    如果我无法将我的系统与DO.Net集成,我会寻找另一个解决方案,但这个EF东西必须离开!

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