【问题标题】:Entity Framework vs LINQ to SQL实体框架与 LINQ to SQL
【发布时间】:2010-09-05 17:44:15
【问题描述】:

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

我的问题是这样的。在尝试决定使用实体框架和 LINQ to SQL 作为 ORM 时,有什么区别?

按照我的理解,实体框架(与 LINQ to Entities 一起使用时)是 LINQ to SQL 的“老大哥”?如果是这种情况 - 它有什么优势? LINQ to SQL 自身无法做到的事情有哪些?

【问题讨论】:

  • 我认为下面的答案应该重新审视一下,因为EF发布已经很长时间了,所以到这里的新开发者可能会得到错误的印象。 EF 自早期发布以来就成为了一个伟大而简单的工具。您只需设置与数据库的连接,就可以满足您所需的 90%。从经验的角度来看,发展非常迅速!从那里开始 - LINQ 是你最好的朋友。它是高度可定制的,MVC 很喜欢它,对于那些说它不好的人来说——首先学习如何使用它(并且掌握 LINQ)!
  • 很清楚 - 现在你没有选择 - MSFT 有效地杀死了 LINQ2SQL 以支持 EF。然而,MSFT 的开源 EF 帮助它减少了吸吮,而且肯定会变得更好。但是对于任何进入 EF 的人来说——一定要明白 EF 中仍然有很多怪癖。我已经发布了大约一个 - stackoverflow.com/questions/305092/…
  • @kape123, (a) LINQ to SQL 没有“死”;它仍然可用; (b) LINQ to SQL 是 Windows Phone 8 开发中的标准数据访问方法。
  • @user3308043,[需要引用]。
  • @Kyralessa - 截至 2010 年(随着 .NET4.0 的发布,我能找到的最新引用),MS acknowledged that,虽然可能会在 LINQ2SQL 上进行一些投资,“大部分我们的整体投资将放在实体框架上。”

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


【解决方案1】:

这里有一些指标...(量化事物!!!)

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

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();

并将其更改为我使用存储库模式的地方 林克

            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 倍...

【讨论】:

    【解决方案2】:

    【讨论】:

    • 答案中的某些内容不正确。如果您使用 Code First,则不需要 EDMX。而且我不明白当您使用 Code First 时 DI 是如何发挥作用的。
    • 另外,Linq to SQL 可以很好地从模型类中填充数据库。不确定它是否也可以生成数据库本身,但生成模式和表属于 Linq to SQL 的能力。
    • 感谢您的回答,我认为使用Linq to SQL时可以使用sqlmetal.exedocs.microsoft.com/en-us/dotnet/framework/tools/…从数据库生成代码/映射
    【解决方案3】:

    我正在为有一个使用 Linq-to-SQL 的大项目的客户工作。项目刚开始的时候,这是显而易见的选择,因为当时Entity Framework还缺少一些主要的特性,而Linq-to-SQL的性能要好很多。

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

    我们正在考虑切换到实体框架,仅用于此功能。很遗憾,微软没有在 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)更具前瞻性。

    【讨论】:

      【解决方案4】:

      Linq-to-SQL

      它是仅支持 SQL Server 的提供程序。这是一种将 SQL Server 数据库表映射到 .NET 对象的映射技术。是微软首次尝试 ORM - Object-Relational Mapper。

      Linq-to-Entities

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

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

      【讨论】:

        【解决方案5】:

        LINQ to SQL

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

        实体框架

        1. 异构数据源: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 数据 API 的未来

        另见:

        【讨论】:

        • 这是最新最详细的答案。
        • 实体框架不使用 LINQ to SQL,比如说,你正在写一个dbSet<Orders>.Where()...ToList()?我认为实体框架反对 LINQ 到 SQL 是一种误导。
        • @mmcrae EF 不使用 L2S,两者都是底层数据库的 linq 提供者。如果您将其解释为 Linq-to-a-database,类似于 linq-to-objects 和 linq-to-xml,那么是的,两者在 linq-to-a-database 中是相似的。但是不,EF 不使用 L2S(反之亦然)。两个完全分离的工具。
        • “推荐用于除...小型项目之外的所有新项目”我不同意。 Code First 是一种快速启动小型项目的方法。除此之外,这个问题的更新很好。
        • 如何定义一个项目是“小”还是“大”?
        【解决方案6】:

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

        由微软提供:

        • 用于 SQL Server、OBDC 和 OLE DB 的 ADO.NET 驱动程序

        通过第三方提供商:

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

        仅举几例。

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

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

        【讨论】:

          【解决方案7】:

          我认为,如果您需要在中间没有奇怪的东西的情况下快速开发一些东西,并且您需要使用实体来代表您的表格:

          Linq2Sql 可以成为一个很好的盟友,将它与 LinQ 一起使用会释放出一个很好的发展时机。

          【讨论】:

          • “中间没有奇怪的东西”,好吧,你这是什么意思。 “中间奇怪的东西”的例子
          • 编辑或删除这个答案会很好,它对现代开发不再有用,并且会让人们走上歧途。
          【解决方案8】:

          我找到了一个很好的答案here,它用简单的话解释了何时使用什么:

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

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

          • 实体框架 - 如果您打算使用此框架 在您的视图或页面中组合来自多个表的数据。做 更清楚的是,上述术语是特定于数据的 在您的视图或页面中进行操作,而不仅仅是显示。这是 理解很重要。

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

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

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

              【解决方案10】:

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

              • LINQ to SQL 是一种快速简便的方法。这意味着,如果您正在做一些较小的事情,您会更快地开始工作并更快地交付。
              • Entity Framework 是一种全面、无拘无束的方式。这意味着,如果您正在处理更大的事情,您将需要更多的前期时间、更慢的开发速度和更大的灵活性。

              【讨论】:

              • 您还倾向于使用 L2S 编写更少的代码行来完成与使用 EF 相同的事情。 EF 中没有延迟加载意味着您​​总是在检查是否加载了某些内容。
              • 布拉德,您对电子商务网站有何建议?我的意思是我看不到除了简单的 CRUD 之外的任何东西......
              • @CoffeeAddict 显然,投票最多的答案前 3 名表示 L2S 用于简单的 CRUD
              • @Banford 在 .NET 4.0 中使用 EF 我认为它比 L2S 更好。 3.5 中的 EF 缺少的 L2S 功能已添加到 .NET 4.0 中的 EF。您现在在 .NET 4.0 中的 EF 中的 LINQ 语句看起来与 L2S 中的几乎相同。在 L2S 提供的基础上,EF 为您提供了一些您现在可以做的额外事情。
              • 这个答案现在已经 5 岁了,而且已经过时了。 Entity Framework 6 现在处于 Beta 阶段,并进行了很大改进,包括延迟加载、枚举支持等。
              【解决方案11】:

              都不支持唯一的 SQL 2008 数据类型。在我看来,不同之处在于 Entity 在未来的某个版本中仍然有机会围绕我的地理数据类型构建模型,而 Linq to SQL 被放弃了,永远不会。

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

              【讨论】:

              • SQL Server 2008 空间数据类型(开放地理空间联盟 OGS)从 Entity Framework 5 开始支持。其他提供者(Devart for Oracle)也支持。见msdn.microsoft.com/en-us/data/dn194325
              【解决方案12】:

              我在实体框架方面的经验并不出色。首先,您必须从 EF 基类继承,所以告别 POCO。您的设计必须围绕 EF。使用 LinqtoSQL,我可以使用我现有的业务对象。此外,没有延迟加载,您必须自己实现。有一些解决方法可以使用 POCO 和延迟加载,但恕我直言,它们存在,因为 EF 还没有准备好。我打算在4.0之后回到它

              【讨论】:

              • 缺乏 POCO 支持是我选择 LINQ to SQL 而不是实体框架的第一大原因。正如他们所承诺的那样,当他们将其合并到下一个版本中时,我可能会重新访问 EF。还有一些额外的项目为 EF 做 POCO,但不够干净。
              • 如果有人(比如我)不知道 POCO 代表什么:Plain Old CLR Object
              • 我真的不明白不支持 POCO 的大惊小怪是什么......这是一个更高层次的抽象家伙。创建一个工厂,注入数据存储库并在那里构建您的 POCO。无论如何,这可能是个好主意。
              • 我听说在 EF 4 中可以使用 POCO
              • POCO 支持现在可用,继承不再是实体类的要求@CoffeeAddict POCO 只是一个简单的对象,不依赖于特定框架,是现代实体框架模式的主要部分
              【解决方案13】:

              我的印象是,如果 Linq2Sql 不能满足您的需求,您的数据库非常庞大或设计非常糟糕。我有大约 10 个大大小小的网站都使用 Linq2Sql。我已经多次查看实体框架,但我找不到在 Linq2Sql 上使用它的充分理由。也就是说,我尝试将我的数据库用作模型,因此我已经在模型和数据库之间建立了一对一的映射。

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

              【讨论】:

              • 您没有抓住重点——即使是小型数据库,您也可能需要不同于数据库表和代码/域对象之间的 1:1 关系的东西。仅取决于您希望在总线/域对象中进行多少抽象。
              • 我已经意识到 :) 今天我喜欢手工编码我的业务实体。我仍然使用 Linq2sql,但仅在我的存储库中使用 Linq2sql 获取数据并将 linq2sql 实体转换为我的自定义业务实体。可能比使用 or-mapper 需要更多的工作,但我仍然喜欢让我的业务层没有任何 OR-mapper 特定代码。
              【解决方案14】:

              Is LINQ to SQL Truly Dead? 由 Jonathan Allen 为 InfoQ.com 撰写

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

              ...

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

              ...

              开发人员不喜欢 [ADO.NET Entity Framework],因为它很复杂。

              ...

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

              【讨论】:

              • 实际上,我们不喜欢 EF,因为它的设计师太差了,而且非常、非常有问题。我从来没有发现它这么复杂。
              • 很多主要的电子商务网站都使用 LINQ to SQL。示例:Redbox、Stackoverflow 等。
              • 我认识很多使用 LINQ to SQL 的优秀开发人员,他们说这些文章完全被夸大了。我同意。 LINQ to SQL 已在强大的 .com 中使用,并且仍然如此。
              • 是的,在 L2EF 查询中对整数属性调用 .ToString() 不会导致异常。
              • @BlueRaja-DannyPflughoeft 5 年多后仍然如此吗?
              【解决方案15】:

              LINQ to SQL 仅支持 Microsoft SQL Server 中可用的数据库表、视图、存储过程和函数的一对一映射。这是一个很棒的 AP​​I,可用于对设计相对良好的 SQL Server 数据库进行快速数据访问构建。 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 上一篇不错的介绍性文章: Introducing LINQ to Relational Data

              【讨论】:

              • 看起来你使用 LINQ to SQL 在 EF 中查询
              • @CoffeeAddict 虽然它们使用 LINQ lambda 在风格上非常相似,但每个 API 都有完全不同的基础。例如,LINQ2SQL 生成 SQL 查询的方式允许使用 SQL 函数,而 L2E 没有,或者至少在 2008 年没有。
              • EF 面向对象的方法使其使用起来非常简单方便,可以非常快速地进行编码和管理。对我来说,这是访问数据的最佳方式。
              • 这个答案已经过时了。现在 Linq to SQL 支持 one2many 映射
              • @GeorgeLanetz 你的意思是以下吗? docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/linq/…
              【解决方案16】:

              如果您的数据库简单明了,LINQ to SQL 就可以了。如果您需要表格顶部的逻辑/抽象实体,请选择实体框架。

              【讨论】:

              • 实体框架允许对数据库顶部进行抽象层。今天许多 OR Mapper 的问题(在我看来)是它们提供了表和类之间的 1 对 1 映射。数据库模型并不总是反映我们在业务模型方面的思考方式。
              • 空间不足。无论如何,根据我上面所说的,我认为你的答案并不完整。
              • 我认为这是一个非常糟糕的建议。 L2S 是很好的无论您的数据库的简单性或复杂性。真正的陷阱是没有适当的关注点分离。如果您尝试合并您的业务层和数据访问层,并将 Linqed 对象用于所有内容,那么您会发现 L2S 受到限制。但这是一个过于简单化和单一化设计的问题。 L2S 是一个很棒的 DAL,如果您考虑将查询和持久性与业务规则分开考虑,从长远来看,您将在很多领域为自己省去很多麻烦。
              • 这什么也没告诉我。用你的话来说什么是简单的?
              • 以及作为需要“逻辑/抽象”的示例是什么意思。是的,我知道抽象是什么,但请在您的上下文中举个例子...向我准确解释您在说什么...描述它,不要只给我一般的俚语...这都与说话者所说的有关那些话,所以我不知道你是什么意思。
              【解决方案17】:

              @lars 发布的那篇文章概述了许多明显的差异,但简短的回答是:

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

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

              【讨论】:

              • 您的报价“L2S 仅适用于 SQL Server(据我所知)”需要更新:开源项目“dblinq”将 LINQ to SQL 程序集替换为可以与 MySQL 通信的程序集, PostgreSQL、Ingres、Firebird、SQLite ... 和 Microsoft SQL(当然)。
              • 等等...所以 EF 不会创建紧密耦合的 DL 对象?
              • 是的,L2S 不是企业级解决方案的原始前提不再正确。我的意思是 StackOverflow 在 L2S 和许多其他 .com 上运行,例如 Redbox 等等。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-04-27
              • 2017-07-07
              • 2011-01-15
              • 1970-01-01
              • 1970-01-01
              • 2013-07-29
              • 1970-01-01
              相关资源
              最近更新 更多