ChatGPT解决这个技术问题 Extra ChatGPT

实体框架与 LINQ to SQL

现在 .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 进行了一些投资,但“我们总体投资的大部分将在实体框架。”

K
Kris

LINQ to SQL 仅支持 Microsoft SQL Server 中可用的数据库表、视图、存储过程和函数的 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 框架 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/…
B
Brad Tutterow

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

LINQ to SQL 是一种快速简便的方法。这意味着如果您正在处理较小的事情,您将更快地完成并更快地交付。

Entity Framework 是一种全力以赴的、无拘无束的方式。这意味着如果您正在处理更大的事情,您将需要更多的前期时间、更慢的开发速度并拥有更大的灵活性。


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

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

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 to 关系方案的推荐数据访问解决方案。


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

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

L2S 是紧密耦合的——对象属性到数据库的特定字段或更正确的对象映射到特定的数据库模式

L2S 仅适用于 SQL Server(据我所知)

EF 允许将单个类映射到多个表

EF 将处理 MM 关系

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 等等。
R
Ryszard Dżegan

LINQ 到 SQL

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

实体框架

异构数据源:支持许多数据提供者 推荐用于所有新项目,除了:当数据源是平面文件 (ADO.NET) 时,小型项目 (LINQ to SQL) 可以在设置模型和映射文件时更改映射而无需重新编译 元数据工件过程要复制输出目录 .edmx(实体数据模型),其中包含: SSDL(存储模式定义语言) CSDL(概念模式定义语言) MSL(映射规范语言) 一对一、一对多、多对一表和类之间的映射 支持继承:TPH(每个层次结构的表) TPT(每个类型的表) TPC(每个具体类的表) 支持复杂类型 代码优先、模型优先、存储优先的方法 以应用程序为中心的数据库视图 创建SQL Server 团队 Microsoft 数据 API 的未来

也可以看看:

LINQ To SQL 与实体框架

LINQ to SQL 和实体框架之间的区别

实体框架与 LINQ TO SQL


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

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


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

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

使用哪个框架的基本经验法则是如何计划在表示层中编辑数据。 Linq-To-Sql - 如果您计划在表示层中编辑数据的一对一关系,请使用此框架。这意味着您不打算在任何一个视图或页面中组合来自多个表的数据。实体框架 - 如果您计划在视图或页面中组合来自多个表的数据,请使用此框架。为了更清楚地说明这一点,上述术语特定于将在您的视图或页面中操作的数据,而不仅仅是显示。理解这一点很重要。使用实体框架,您可以将表格数据“合并”在一起,以可编辑的形式呈现给表示层,然后在提交该表单时,EF 将知道如何更新各个表中的所有数据。选择 EF 而不是 L2S 可能有更准确的理由,但这可能是最容易理解的。 L2S 不具备合并数据以进行视图呈现的能力。


t
terjetyl

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

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


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

你可以在这里找到一个很好的比较:

https://i.stack.imgur.com/TW8YY.jpg

http://www.dotnet-tricks.com/Tutorial/entityframework/1M5W300314-Difference-between-LINQ-to-SQL-and-Entity-Framework.html

http://www.c-sharpcorner.com/blogs/entity-framework-vs-linq-to-sql1


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

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

微软提供:

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

通过第三方提供商:

MySQL

甲骨文

DB2

维斯塔数据库

SQLite

PostgreSQL

Informix

U2

赛贝斯

协同效应

火鸟

Npgsql

仅举几例。

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

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


B
Banford

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

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


v
vintana

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


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

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

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


从 Entity Framework 5 开始支持 SQL Server 2008 空间数据类型(开放地理空间联盟 OGS)。还支持其他提供程序(Devart for Oracle)。请参阅msdn.microsoft.com/en-us/data/dn194325
R
Ramon de Klein

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


A
Anujith

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

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


“中间没有奇怪的东西”,好吧,你这是什么意思。 “中间奇怪的东西”的例子
编辑或删除这个答案会很好,它对现代开发不再有用,并且会让人们走上错误的轨道。
U
Umang Patwa

Linq 到 SQL

它是仅支持 SQL Server 的提供程序。这是一种将 SQL Server 数据库表映射到 .NET 对象的映射技术。是微软在 ORM 上的第一次尝试——对象关系映射器。

链接到实体

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

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


R
Robert Green MBA

这里有一些指标家伙......(量化的东西!!!!)

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

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

https://i.stack.imgur.com/TkWAZ.jpg