实体框架vs LINQ toSQL

现在. NET v3.5 SP1已经发布(与VS2008 SP1一起发布),我们现在可以访问. NET实体框架。

我的问题是,当试图决定使用Entity Framework和LINQ来SQLORM时,有什么区别?

在我的理解中,实体框架(当与LINQ to Entities一起使用时)是LINQ toSQL的“大哥”?如果是这样的话-它有什么优势?它能做什么LINQ toSQL本身不能做的?

288097 次浏览

这篇文章中列出了一些明显的区别,但简短的回答是:

  • L2S紧密耦合-对象属性到数据库的特定字段,或者更正确地对象映射到特定的数据库模式
  • L2S仅适用于SQL服务器(据我所知)
  • EF允许将单个类映射到多个表
  • EF将处理M-M关系
  • EF将有能力瞄准任何ADO.NET数据提供商

最初的前提是L2S用于快速开发,EF用于更多“企业”的n-层应用程序,但这种销售L2S有点短。

我认为快速而肮脏的答案是

  • LINQ toSQL是一种快速简便的方法。这意味着你会更快地开始工作,如果你正在做一些更小的事情,你会更快地交付。
  • 实体框架是一种全力以赴、无限制的方式。这意味着如果你正在做更大的事情,你将需要更多的时间来预先开发,开发速度更慢,并且有更大的灵活性。

如果您的数据库简单明了,LINQ toSQL就可以了。如果您需要表之上的逻辑/抽象实体,请使用实体框架。

LINQ toSQL仅支持MicrosoftSQLServer中可用的数据库表、视图、链轮和函数的1到1映射。它是用于对设计相对良好的SQLServer数据库进行快速数据访问的绝佳API。LINQ2SQL最初随C#3.0和. Net Framework 3.5一起发布。

LINQ to Entities(ADO. Net Entity Framework)是一个ORM(对象关系映射器)API,它允许广泛定义对象域模型及其与许多不同ADO. Net数据提供者的关系。因此,您可以混合和匹配许多不同的数据库供应商、应用程序服务器或协议,以设计从各种表、源、服务等构建的对象的聚合混搭。ADO. Net Framework随. Net Framework 3.5 SP1一起发布。

这是一篇关于MSDN的很好的介绍性文章:将LINQ引入关系数据

乔纳森·艾伦为InfoQ.com

马特·沃伦将[LINQ toSQL]描述为“根本不应该存在”的东西。本质上,它只是帮助他们开发LINQ,直到真正的ORM准备就绪。

Entity Framework的规模导致它错过了. NET 3.5/Visual Studio 2008的截止日期。它及时完成了不幸命名为“. NET 3.5 Service Pack 1”,它更像是一个主要版本而不是服务包。

开发人员不喜欢[ADO.NET实体框架],因为它的复杂性。

从. NET 4.0开始,LINQ to Entities将成为LINQ to关系方案的推荐数据访问解决方案。

我的印象是,如果Linq2Sql不符合您的需求,您的数据库非常丰富或设计非常糟糕。我有大约10个网站,无论大小都使用Linq2Sql。我已经看了很多次实体框架,但我找不到在Linq2Sql上使用它的好理由。也就是说,我尝试使用我的数据库作为模型,所以我已经在模型和数据库之间有了1到1的映射。

在我目前的工作中,我们有一个包含200多个表的数据库。一个有很多糟糕解决方案的旧数据库,所以我可以看到Entity Framework比Linq2Sql的好处,但我仍然更愿意重新设计数据库,因为数据库是应用程序的引擎,如果数据库设计糟糕且速度慢,那么我的应用程序也会很慢。在这样的数据库上使用Entity Framework似乎是掩盖坏模型的快速解决方案,但它永远无法掩盖你从这样的数据库中获得的糟糕性能。

我使用Entity Framework的经验一直不太好。首先,你必须从EF基类继承,所以告别POCO。你的设计必须围绕EF。使用LinqtoSQL,我可以使用我现有的业务对象。此外,没有延迟加载,你必须自己实现。有一些使用POCO和延迟加载的变通方法,但恕我直言,它们存在,因为EF还没有准备好。我计划在4.0之后回来

我认为如果你需要快速开发一些东西,中间没有奇怪的东西,并且你需要有实体代表你的表:

Linq2Sql可以是一个很好的联盟,将它与LinQ一起使用可以释放一个很好的开发时机。

两者都还不支持唯一SQL2008数据类型。从我的角度来看,不同之处在于实体仍然有机会在未来的某个版本中围绕我的地理数据类型构建模型,而Linq toSQL,被遗弃,永远不会。

想知道nHibernate或OpenAccess是怎么回事…

我发现在使用EF时不能在同一数据库模型中使用多个数据库。但在linq2sql中,我可以通过在模式名称前加上数据库名称。

这是我最初开始使用linq2sql的原因之一。我不知道EF是否还允许此功能,但我记得读到它的目的是不允许此功能。

我找到了一个非常好的答案这里,它用简单的单词解释了何时使用什么:

使用哪个框架的基本经验法则是如何计划在表示层中编辑数据。

  • Linq-To-Sql-如果您计划一对一编辑,请使用此框架表示层中数据的关系。意思是你不打算在任何一个视图中组合来自多个表的数据或页面。

  • 实体框架-如果您计划使用此框架组合视图或页面中多个表中的数据。使更清楚的是,上述术语是特定于数据的在您的视图或页面中操作,而不仅仅是显示。这是#36825;要理解

使用实体框架,您可以将表中的数据“合并”在一起以可编辑的形式呈现到表示层,然后提交表单后,EF将知道如何更新所有数据从不同的表。

选择EF而不是L2S可能有更准确的理由,但是这可能是最容易理解的。L2S不能够合并数据以进行视图呈现。

这里的答案涵盖了Linq2Sql和EF之间的许多差异,但有一个关键点没有得到太多关注:Linq2Sql仅支持SQLServer,而EF提供以下RDBMS的提供程序:

由Microsoft提供:

  • SQLServer、OBDC和OLE DB的ADO.NET驱动程序

通过第三方提供商:

  • mysql
  • Oracle
  • DB2
  • VistaDB
  • SQLite
  • PostgreSQL
  • Informix
  • U2
  • 赛贝斯
  • Synergex
  • 火鸟
  • Npgsql

举几个例子。

这使得EF成为关系数据存储上的一个强大的编程抽象,这意味着无论底层数据存储如何,开发人员都可以使用一致的编程模型。这在您正在开发希望确保能够与各种常见RDBMS互操作的产品的情况下非常有用。

这种抽象有用的另一种情况是,您是开发团队的一员,该团队与许多不同的客户或组织内的不同业务部门合作,您希望通过减少他们必须熟悉的RDBMS的数量来提高开发人员的生产力,以便在不同的RDBMS之上支持一系列不同的应用程序。

LINQ到SQL

  1. 同构数据源:SQL服务器
  2. 仅推荐用于数据结构设计良好的小型项目
  3. 可以更改映射,而无需重新编译SqlMetal.exe
  4. . dbml(数据库标记语言)
  5. 表和类之间的一对一映射
  6. 支持TPH继承
  7. 不支持复杂类型
  8. 存储优先方法
  9. 以数据库为中心的数据库视图
  10. 由C#团队创建
  11. 支持但不打算进一步改进

实体框架

  1. 异质性数据来源:支持多个数据提供商
  2. 推荐用于所有新项目,除了:
    • 小型(LINQ到SQL)
    • 当数据源是平面文件时(ADO.NET)
  3. 设置模型和映射文件时可以更改映射而无需重新编译元数据工件过程复制到输出目录
  4. . edmx(实体数据模型),其中包含:
    • SSDL(存储架构定义语言)
    • CSDL(概念模式定义语言)
    • 映射规范语言
  5. 表和类之间的一对一、一对多、多对一映射
  6. 支持继承:
    • TPH(每个层次的表)
    • TPT(每个类型的表)
    • TPC(表每具体类)
  7. 支持复杂类型
  8. 代码优先、模型优先、存储优先
  9. 以应用程序为中心的数据库视图
  10. 由SQL服务器团队创建
  11. Microsoft Data API的未来

另见:

LINQ到SQL实体框架
它只适用于SQL服务器数据库它可以使用各种数据库,如Oracle,DB2,MySQL,SQLServer等。
它生成. dbml来维护关系它最初生成一个. edmx文件。使用3个不同的文件维护关系;. csdl、. msl和. ssdl
它不支持复杂类型它支持复杂类型
它不能从模型生成数据库它可以从模型生成数据库
它只允许实体类和关系表/视图之间的一对一映射它允许实体类和关系表/视图之间的一对一、一对多、多对多映射
它允许您使用DataContext查询数据它允许您使用EntitySQL、ObjectContext、DbContext查询数据
它可以用于快速应用程序开发只有与SQL服务器它可用于RDBMS的快速应用程序开发,如SQLServer、Oracle、PostgreSQL等。

Linq-to-SQL

它是仅支持SQL服务器的提供者。它是一种将SQL服务器数据库表映射到. NET对象的映射技术。是Microsoft首次尝试ORM-对象关系映射器。

链接到实体

是相同的想法,但在后台使用实体框架,作为ORM-再次来自微软,它支持多个数据库实体框架的主要优点是开发人员可以在任何数据库上工作,无需学习语法即可在不同的数据库上执行任何操作

根据我的个人经验,Ef更好(如果你不知道SQL)与用lambda编写的EF原因LINQ语言相比,LINQ的性能要快一些。

我正在为一个使用Linq-to-SQL的大型项目的客户工作。当项目开始时,它是显而易见的选择,因为当时实体框架缺乏一些主要功能,Linq-to-SQL的性能要好得多。

现在EF已经发展,Linq-to-SQL缺乏异步支持,这对于高度可扩展的服务非常有用。我们有时每秒有100多个请求,尽管我们已经优化了数据库,但大多数查询仍然需要几毫秒才能完成。由于同步数据库调用,线程被阻塞,无法用于其他请求。

我们正在考虑切换到Entity Framework,仅仅是为了这个功能。很遗憾,微软没有在Linq-to-SQL中实现异步支持(或者开源,这样社区就可以做到)。

增编2018年12月: Microsoft正在向. NET Core和Linq-2-迁移SQL. NET Core不支持,因此您需要迁移到EF以确保将来可以迁移到EF. Core。

还有一些其他选项需要考虑,例如LLBLGen。这是一个成熟的ORM解决方案,已经存在了很长时间,并且已经被证明比MS数据解决方案(ODBC,ADO,ADO.NET,Linq-2-SQL,EF,EF.core)更加面向未来。

这里有一些指标伙计…(量化事物!!!!)

我在使用实体框架的地方进行了这个查询

var result = (from metattachType in _dbContext.METATTACH_TYPEjoin lineItemMetattachType in _dbContext.LINE_ITEM_METATTACH_TYPE on metattachType.ID equals lineItemMetattachType.METATTACH_TYPE_IDwhere (lineItemMetattachType.LINE_ITEM_ID == lineItemId && lineItemMetattachType.IS_DELETED == false&& metattachType.IS_DELETED == false)select new MetattachTypeDto(){Id = metattachType.ID,Name = metattachType.NAME}).ToList();

并将其更改为这个,我正在使用存储库模式linq

            return await _attachmentTypeRepository.GetAll().Where(x => !x.IsDeleted).Join(_lineItemAttachmentTypeRepository.GetAll().Where(x => x.LineItemId == lineItemId && !x.IsDeleted),attachmentType => attachmentType.Id,lineItemAttachmentType => lineItemAttachmentType.MetattachTypeId,(attachmentType, lineItemAttachmentType) => new AttachmentTypeDto{Id = attachmentType.Id,Name = attachmentType.Name}).ToListAsync().ConfigureAwait(false);

linq-to-sql

            return (from attachmentType in _attachmentTypeRepository.GetAll()join lineItemAttachmentType in _lineItemAttachmentTypeRepository.GetAll() on attachmentType.Id equals lineItemAttachmentType.MetattachTypeIdwhere (lineItemAttachmentType.LineItemId == lineItemId && !lineItemAttachmentType.IsDeleted && !attachmentType.IsDeleted)select new AttachmentTypeDto(){Id = attachmentType.Id,Name = attachmentType.Name}).ToList();

另外,请知道Linq-to-Sql比Linq快14倍…

输入图片描述