现在 .NET v3.5 SP1 已经发布(连同 VS2008 SP1),我们现在可以访问 .NET 实体框架。
我的问题是这个。当尝试在使用实体框架和 LINQ to SQL 作为 ORM 之间做出决定时,有什么区别?
按照我的理解,实体框架(与 LINQ to Entities 一起使用时)是 LINQ to SQL 的“老大哥”?如果是这种情况 - 它有什么优势?LINQ to SQL 无法单独完成哪些功能?
现在 .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 真的死了吗?乔纳森艾伦为 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 用于快速开发,而 EF 用于更多“企业级”n 层应用程序,但这就是销售 L2S 有点短。
也可以看看:
我在实体框架方面的经验并不出色。首先,您必须从 EF 基类继承,所以告别 POCO。您的设计必须围绕 EF。使用 LinqtoSQL,我可以使用我现有的业务对象。此外,没有延迟加载,您必须自己实现。有一些解决方法可以使用 POCO 和延迟加载,但恕我直言,它们存在,因为 EF 还没有准备好。我打算在4.0之后回来
我在这里找到了一个很好的答案,它解释了何时使用简单的词语:
使用哪个框架的基本经验法则是如何计划在表示层中编辑数据。
Linq-To-Sql - 如果您计划在表示层中编辑数据的一对一关系,请使用此框架。这意味着您不打算在任何一个视图或页面中组合来自多个表的数据。
实体框架- 如果您计划在视图或页面中组合来自多个表的数据,请使用此框架。为了更清楚地说明这一点,上述术语特定于将在您的视图或页面中操作的数据,而不仅仅是显示。理解这一点很重要。
使用实体框架,您可以将表格数据“合并”在一起,以可编辑的形式呈现给表示层,然后在提交该表单时,EF 将知道如何更新各个表中的所有数据。
选择 EF 而不是 L2S 可能有更准确的理由,但这可能是最容易理解的。L2S 不具备合并数据以进行视图呈现的能力。
我的印象是,如果 Linq2Sql 不符合您的需求,您的数据库非常庞大或设计非常糟糕。我有大约 10 个大大小小的网站都使用 Linq2Sql。我已经多次查看实体框架,但我找不到在 Linq2Sql 上使用它的充分理由。也就是说,我尝试将我的数据库用作模型,因此我已经在模型和数据库之间建立了一对一的映射。
在我目前的工作中,我们有一个包含 200 多个表的数据库。一个有很多糟糕解决方案的旧数据库,所以我可以看到 Entity Framework 优于 Linq2Sql 但我仍然更愿意重新设计数据库,因为数据库是应用程序的引擎,如果数据库设计不当并且速度较慢,那么我的应用程序也会很慢。在这样的数据库上使用实体框架似乎是掩饰坏模型的快速修复,但它永远无法掩饰你从这样的数据库中获得的糟糕性能。
你可以在这里找到一个很好的比较:
http://www.c-sharpcorner.com/blogs/entity-framework-vs-linq-to-sql1
这里的答案涵盖了 Linq2Sql 和 EF 之间的许多差异,但有一个关键点没有引起太多关注:Linq2Sql 仅支持 SQL Server,而 EF 具有以下 RDBMS 的提供程序:
微软提供:
通过第三方提供商:
仅举几例。
这使得 EF 成为对关系数据存储的强大编程抽象,这意味着无论底层数据存储如何,开发人员都可以使用一致的编程模型。这在您正在开发一个希望确保与广泛的常见 RDBMS 互操作的产品的情况下非常有用。
这种抽象很有用的另一种情况是,您是一个开发团队的一员,该团队与许多不同的客户或组织内的不同业务部门合作,并且您希望通过减少他们必须成为的 RDBMS 的数量来提高开发人员的生产力熟悉以便在不同的 RDBMS 之上支持一系列不同的应用程序。
我发现在使用 EF 时,我无法在同一个数据库模型中使用多个数据库。但是在 linq2sql 中,我可以通过在模式名称前面加上数据库名称。
这是我最初开始使用 linq2sql 的原因之一。我不知道 EF 是否还允许此功能,但我记得读过它的本意是不允许此功能。
如果您的数据库简单明了,LINQ to SQL 就可以了。如果您需要表格顶部的逻辑/抽象实体,请选择实体框架。
两者都不支持唯一的 SQL 2008 数据类型。从我的角度来看,不同之处在于 Entity 在未来的某个版本中仍然有机会围绕我的地理数据类型构建模型,而 Linq to SQL 被放弃,永远不会。
想知道 nHibernate 或 OpenAccess 是怎么回事……
我认为,如果您需要快速开发一些中间没有奇怪的东西的东西,并且您需要该工具来拥有代表您的表的实体:
Linq2Sql 可以成为一个很好的盟友,将它与 LinQ 一起使用会释放出一个很好的发展时机。
我正在为有一个使用 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)更具前瞻性。
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 倍...