现在 .NET v3.5 SP1 已经发布(连同 VS2008 SP1),我们现在可以访问 .NET 实体框架。
我的问题是这个。当尝试在使用实体框架和 LINQ to SQL 作为 ORM 之间做出决定时,有什么区别?
按照我的理解,实体框架(与 LINQ to Entities 一起使用时)是 LINQ to SQL 的“老大哥”?如果是这种情况 - 它有什么优势? LINQ to SQL 无法单独完成哪些功能?
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 是一种快速简便的方法。这意味着如果您正在处理较小的事情,您将更快地完成并更快地交付。
Entity Framework 是一种全力以赴的、无拘无束的方式。这意味着如果您正在处理更大的事情,您将需要更多的前期时间、更慢的开发速度并拥有更大的灵活性。
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 关系方案的推荐数据访问解决方案。
@lars 发布的那篇文章中概述了许多明显的差异,但简短的回答是:
L2S 是紧密耦合的——对象属性到数据库的特定字段或更正确的对象映射到特定的数据库模式
L2S 仅适用于 SQL Server(据我所知)
EF 允许将单个类映射到多个表
EF 将处理 MM 关系
EF 将能够针对任何 ADO.NET 数据提供程序
最初的前提是 L2S 用于快速开发,而 EF 用于更多“企业级”n 层应用程序,但这就是销售 L2S 有点短。
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 是一种误导。
我在实体框架方面的经验并不出色。首先,您必须从 EF 基类继承,所以告别 POCO。您的设计必须围绕 EF。使用 LinqtoSQL,我可以使用我现有的业务对象。此外,没有延迟加载,您必须自己实现。有一些解决方法可以使用 POCO 和延迟加载,但恕我直言,它们存在,因为 EF 还没有准备好。我打算在4.0之后回来
我找到了一个很好的答案 here,它解释了何时使用简单的词语:
使用哪个框架的基本经验法则是如何计划在表示层中编辑数据。 Linq-To-Sql - 如果您计划在表示层中编辑数据的一对一关系,请使用此框架。这意味着您不打算在任何一个视图或页面中组合来自多个表的数据。实体框架 - 如果您计划在视图或页面中组合来自多个表的数据,请使用此框架。为了更清楚地说明这一点,上述术语特定于将在您的视图或页面中操作的数据,而不仅仅是显示。理解这一点很重要。使用实体框架,您可以将表格数据“合并”在一起,以可编辑的形式呈现给表示层,然后在提交该表单时,EF 将知道如何更新各个表中的所有数据。选择 EF 而不是 L2S 可能有更准确的理由,但这可能是最容易理解的。 L2S 不具备合并数据以进行视图呈现的能力。
我的印象是,如果 Linq2Sql 不符合您的需求,您的数据库非常庞大或设计非常糟糕。我有大约 10 个大大小小的网站都使用 Linq2Sql。我已经多次查看实体框架,但我找不到在 Linq2Sql 上使用它的充分理由。也就是说,我尝试将我的数据库用作模型,因此我已经在模型和数据库之间建立了一对一的映射。
在我目前的工作中,我们有一个包含 200 多个表的数据库。一个旧数据库,有很多糟糕的解决方案,所以我可以看到 Entity Framework 优于 Linq2Sql 但我仍然更愿意重新设计数据库,因为数据库是应用程序的引擎,如果数据库设计不当并且速度较慢,那么我的应用程序也会很慢。在这样的数据库上使用实体框架似乎是掩饰坏模型的快速修复,但它永远无法掩饰你从这样的数据库中获得的糟糕性能。
你可以在这里找到一个很好的比较:
https://i.stack.imgur.com/TW8YY.jpg
http://www.c-sharpcorner.com/blogs/entity-framework-vs-linq-to-sql1
Linq to SQL
时可以使用 sqlmetal.exe
docs.microsoft.com/en-us/dotnet/framework/tools/… 从数据库生成代码/映射
这里的答案涵盖了 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 之上支持一系列不同的应用程序。
我发现在使用 EF 时,我无法在同一个数据库模型中使用多个数据库。但是在 linq2sql 中,我可以通过在模式名称前面加上数据库名称。
这是我最初开始使用 linq2sql 的原因之一。我不知道 EF 是否还允许此功能,但我记得读过它的本意是不允许此功能。
如果您的数据库简单明了,LINQ to SQL 就可以了。如果您需要表格顶部的逻辑/抽象实体,请选择实体框架。
两者都不支持唯一的 SQL 2008 数据类型。从我的角度来看,不同之处在于 Entity 在未来的某个版本中仍然有机会围绕我的地理数据类型构建模型,而 Linq to SQL 被放弃,永远不会。
想知道 nHibernate 或 OpenAccess 是怎么回事……
我正在为有一个使用 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)更具前瞻性。
我认为,如果您需要快速开发一些中间没有奇怪的东西的东西,并且您需要该工具来拥有代表您的表的实体:
Linq2Sql 可以成为一个很好的盟友,将它与 LinQ 一起使用会释放出一个很好的发展时机。
Linq 到 SQL
它是仅支持 SQL Server 的提供程序。这是一种将 SQL Server 数据库表映射到 .NET 对象的映射技术。是微软在 ORM 上的第一次尝试——对象关系映射器。
链接到实体
是相同的想法,但在后台使用实体框架,作为 ORM - 再次来自微软,它支持多个数据库实体框架的主要优点是开发人员可以在任何数据库上工作,无需学习语法来对不同的不同数据库执行任何操作
根据我的个人经验,与用 lambda 编写的 EF 原因 LINQ 语言相比,LINQ 中的性能更好(如果您不了解 SQL)。
这里有一些指标家伙......(量化的东西!!!!)
我在使用实体框架的地方进行了这个查询
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