实体框架与LINQ to SQL

时间:2008-08-12 11:04:12

标签: .net entity-framework linq-to-sql

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

我的问题是这个。在尝试使用Entity Framework和LINQ to SQL作为ORM时,有什么区别?

我理解它的方式,实体框架(与LINQ to Entities一起使用时)是LINQ to SQL的“大哥”?如果是这种情况 - 它有什么优势?它能做什么,LINQ to SQL不能独立完成?

18 个答案:

答案 0 :(得分:468)

LINQ to SQL仅支持Microsoft SQL Server中可用的数据库表,视图,Sproc和函数的1对1映射。这是一个很好的API,用于快速数据访问构建到相对精心设计的SQL Server数据库。 LINQ2SQL最初是与C#3.0和.Net Framework 3.5一起发布的。

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

这是关于MSDN的一篇很好的介绍性文章: Introducing LINQ to Relational Data

答案 1 :(得分:195)

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

  • LINQ to SQL是一种快速简便的方法。这意味着如果您正在开展更小的工作,您将会更快上手,并且能够更快地完成工作。
  • 实体框架是一种全面,无拘无束的方式。这意味着如果你正在做更大的事情,你需要花更多的时间在前面,发展得更慢,并且具有更大的灵活性。

答案 2 :(得分:106)

Jonathan Allen为InfoQ.com

Is LINQ to SQL Truly Dead?

  

Matt Warren将[LINQ to SQL]描述为“甚至从未存在过”。从本质上讲,它应该是替代它来帮助他们开发LINQ,直到真正的ORM准备就绪。

     

...

     

实体框架的规模导致它错过了.NET 3.5 / Visual Studio 2008的最后期限。它很快就被命名为“.NET 3.5 Service Pack 1”,它更像是一个主要版本而不是一个服务包。

     

...

     

由于复杂性,开发人员不喜欢[ADO.NET Entity Framework]。

     

...

     

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

答案 3 :(得分:92)

@lars发表的文章中列出了许多明显的差异,但简短的回答是:

  • L2S紧密耦合 - 对象属性到数据库的特定字段或更正确的对象映射到特定的数据库模式
  • L2S仅适用于SQL Server(据我所知)
  • EF允许将单个类映射到多个表
  • EF将处理M-M关系
  • EF将能够定位任何ADO.NET数据提供程序

最初的前提是L2S用于快速开发,而EF用于更多“企业级”n层应用程序,但这就是销售L2S的一小段时间。

答案 4 :(得分:72)

LINQ to SQL

  1. 同构数据源:SQL Server
  2. 仅适用于数据结构设计合理的小型项目
  3. 无需重新使用SqlMetal.exe
  4. 即可更改映射
  5. .dbml(数据库标记语言)
  6. 表和类之间的一对一映射
  7. 支持TPH继承
  8. 不支持复杂类型
  9. 存储优先方法
  10. 以数据库为中心的数据库视图
  11. 由C#团队创建
  12. 支持但未进一步改进
  13. 实体框架

    1. Heterogeneus数据源:Support many data providers
    2. 建议所有新项目除外:
      • 小的(LINQ to SQL)
      • 当数据源是平面文件(ADO.NET)时
    3. 在设置模型和映射文件元数据工件进程以复制到输出目录时,无需重新编译即可更改映射
    4. .edmx(实体数据模型),其中包含:
      • SSDL(存储架构定义语言)
      • CSDL(概念架构定义语言)
      • MSL(映射规范语言)
    5. 表和类之间的一对一,一对多,多对一映射
    6. 支持继承:
      • TPH(每层次表)
      • TPT(每种类型的表)
      • TPC(每混凝土类别表)
    7. 支持复杂类型
    8. 代码优先,模型优先,存储优先方法
    9. 以数据库为中心的应用程序视图
    10. 由SQL Server团队创建
    11. Microsoft Data API的未来

    12. 另见:

答案 5 :(得分:51)

我对实体框架的体验并不那么出色。首先,你必须继承EF基类,所以要对POCO说再见。您的设计必须围绕EF。使用LinqtoSQL,我可以使用现有的业务对象。此外,没有延迟加载,您必须自己实现。有一些工作要使用POCO和延迟加载,但它们存在恕我直言,因为EF尚未准备好。我打算在4.0之后回来。

答案 6 :(得分:47)

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

  

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

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

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

  •   
     

使用实体框架,您可以将表格数据“合并”在一起   以可编辑的形式呈现给表示层,然后   提交该表单时,EF将知道如何更新所有数据   来自各种表格。

     

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

答案 7 :(得分:36)

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

在我目前的工作中,我们有一个包含200多个表的数据库。一个包含大量不良解决方案的旧数据库,因此我可以看到实体框架优于Linq2Sql,但我仍然希望重新设计数据库,因为数据库是应用程序的引擎,如果数据库设计错误,那么我的应用程序速度慢也会很慢。在这样的数据库上使用Entity框架似乎是一个快速修复来掩盖坏模型,但它永远无法掩盖从这样的数据库中获得的糟糕性能。

答案 8 :(得分:25)

答案 9 :(得分:23)

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

由Microsoft提供:

  • SQL Server,OBDC和OLE DB的ADO.NET驱动程序

通过第三方提供商:

  • MySQL的
  • 甲骨文
  • DB2
  • VistaDB的
  • SQLite的
  • 的PostgreSQL
  • 的Informix
  • U2
  • 的Sybase
  • Synergex的
  • 火鸟
  • Npgsql的

仅举几例。

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

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

答案 10 :(得分:15)

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

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

答案 11 :(得分:12)

如果您的数据库简单明了,LINQ to SQL就可以了。如果您需要在表顶部使用逻辑/抽象实体,那么请转到实体框架。

答案 12 :(得分:8)

两者都不支持唯一的SQL 2008数据类型。与我的观点不同的是,实体仍然有机会在未来的某个版本中围绕我的地理数据类型构建模型,并且Linq to SQL被抛弃,永远不会。

想知道nHibernate或OpenAccess是什么......

答案 13 :(得分:7)

我认为如果你需要快速开发一些东西,而中间没有奇怪的东西,你需要设施来代表你的桌子:

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

答案 14 :(得分:6)

我正在为有一个使用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)更具有前瞻性。

答案 15 :(得分:2)

LINQ to SQL和Entity Framework在表面上看起来很相似。他们都提供 LINQ使用数据模型查询数据库。

LINQ to SQL是从LINQ项目发展而来的,该项目来自团队合作 语言开发。实体框架是数据可编程性团队的一个项目,专注于实体SQL语言。 Microsoft完全无意将LINQ to depric化为SQL。

LINQ to SQL仍然是ADO.NET的一部分,而Entity框架具有单独的API。 实体框架是LINQ to SQL的更高版本.Entity框架使用实体数据模型在您的应用程序和数据存储之间进行桥接。实体数据模型(EDM)提供概念模式的定义以及与数据库交互所需的数据库模式信息,最后提供链接到两者的映射模式。

以下是Entity Framework(实体数据模型)执行的一些任务。

•自动从模型生成类并更新这些类 在模型改变的任何时候动态地动态。

•负责所有数据库连接,以便开发人员不必为编写与数据库交互的代码而负担。

•提供查询模型而不是数据库的通用查询语法,然后将这些查询转换为数据库可以理解的查询。

•提供一种机制,用于跟踪模型对象的更改 在应用程序中使用并处理数据库的更新。

答案 16 :(得分:2)

  

LINQ到SQL

它是仅支持SQL Server的提供程序。它是将SQL Server数据库表映射到.NET对象的映射技术。是Microsoft首次尝试使用ORM - 对象关系映射器。

  

LINQ到实体

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

  

根据我的个人经验,Ef更好(如果您不了解SQL)   与使用lambda编写的LINQ语言的EF原因相比,LINQ中的性能要快一点。

答案 17 :(得分:2)

以下是一些衡量指标的人……(正在量化事情!!!)

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

var result = (from metattachType in _dbContext.METATTACH_TYPE
                join lineItemMetattachType in _dbContext.LINE_ITEM_METATTACH_TYPE on metattachType.ID equals lineItemMetattachType.METATTACH_TYPE_ID
                where (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.MetattachTypeId
                    where (lineItemAttachmentType.LineItemId == lineItemId && !lineItemAttachmentType.IsDeleted && !attachmentType.IsDeleted)
                    select new AttachmentTypeDto()
                    {
                        Id = attachmentType.Id,
                        Name = attachmentType.Name
                    }).ToList();

另外,请注意,Linq-to-Sql比Linq快14倍...

enter image description here