为什么我应该使用Entity Framework而不是Linq2SQL?

9
请明确一点,我并不要求进行已经在SO上反复讨论的并排比较。我也不关心Linq2Sql是否已经死亡。我的问题是这样的……
我正在为一个非营利组织构建内部应用程序。我是唯一的开发人员。我们总是使用SQL Server作为数据库后端。我也设计和构建数据库。我已经成功地使用过L2S几次了。
考虑到所有这些因素,有人能给我一个使用EF而不是L2S的充分理由吗?
我在本周末参加了Code Camp,在一个长达一小时的EF演示之后,我问了同样的问题。演讲者的回答是,“L2S已经死了……”好的,那就这样吧!不是!(请参见这里

我了解EF是微软未来希望我们使用的内容(在这里查看),并且它提供了更多的自定义选项。但我无法确定在这种环境下,任何一个选项是否有用或者是否重要。

我们这里面临的一个特别问题是,我继承了基于4个不同SQL数据库构建的核心应用程序。L2S对此有很大困难,但当我问上述演讲者EF是否会在这方面帮助我时,他说“不会!”


有人可以详细解释一下为什么要点踩吗?这个帖子应该是 CW(社区 Wiki)还是其他什么东西吗?我不介意被点踩,但我更想知道为什么,这样下次我就可以做得更好了。 - Refracted Paladin
我对你关于多个数据库的评论感到好奇。难点在哪里?Linq to SQL有一个DataContext的重载,允许您指定要打开的数据库,并且在任何情况下,多个数据库的连接都是一个问题。 - Robert Harvey
@Robert Harvey:难点在于这种情况......在一个名为CMO的数据库中,有一个名为tblDiagnosisCues的表。在一个名为MCP的数据库中,有一个名为tblPlanDiagnosis的表。这两个表通过FK诊断线索ID相连。当我想要获取计划的诊断时,我必须从CMO数据库中获取描述信息。我曾希望EF能够简化此过程,通过允许我创建一个实体来获取诊断,而不关心数据来自何处。清楚了吗?顺便说一下,我没有设计这些数据库! - Refracted Paladin
是的,这更清晰了。问题不在于能否将数据建模为类,而在于如何从两个不同的数据库中获取有效的连接。在SQL Server中,您可以通过运行sp_addlinkedserver存储过程将两个SQL数据库链接在一起,然后在SQL语句中使用它们各自的服务器名称作为表名前缀来连接要连接的表。有关更多详细信息,请参见http://msdn.microsoft.com/en-us/library/ms190479.aspx。 - Robert Harvey
使用 Linq to SQL 在多个数据库上执行表连接,请查看此处:https://dev59.com/enRC5IYBdhLWcg3wRO3k - Robert Harvey
10个回答

8

使用 EF 可以获得一个映射层(即您的实体),将类对象和数据库表之间进行映射。如果您需要这种灵活性,或者更喜欢领域驱动设计模型(而不是表驱动设计),那么考虑使用 EF 可能是值得的。Linq to SQL 主要是一个将类映射到表的工具。


所以,为了尝试澄清一下,您是在说,例如,如果我有一些数据库是我无法控制的,EF将允许我创建类,使其对我的应用程序有意义,而不考虑表结构,而L2S则不能? - Refracted Paladin
1
大部分情况下,显然EF不能弥补真正糟糕的数据库设计,但它可以极大地改善情况。此外,有些人更喜欢基于领域的设计,其中底层表实际上可以与实际领域对象不同。 - Robert Harvey
@Robert Harvey:那么,可以这样说,除了上述继承的数据库之外,由于我设计所有的数据库,因此EF在这个领域的好处是微不足道的?当然,除非我设计了一个糟糕的数据库,然后试图使用它。 - Refracted Paladin
2
如果您的设计基于表格,并且您对将表格直接映射到对象感到满意,那么您应该继续使用Linq to SQL。如果您需要使用EF进行映射工作,或者连接到另一个不是SQL Server的数据库,您可以随时向解决方案添加EF数据上下文。 - Robert Harvey
当你进入更大的应用程序时,不断担心数据库会成为一个主要问题。在一个良好、正确设置的O/RM(如NHibernate)中,你甚至不需要在编码时考虑数据库——它会自己处理。当然,Entity Framework 还远远达不到这个水平。 - BlueRaja - Danny Pflughoeft
显示剩余2条评论

7
我不使用Linq2SQL的一个主要原因是它存在一个重大的隐式设计缺陷:
DataContext的推荐最佳实践是以短暂的“工作单元”方式使用。很好,但首先创建和处理这个对象是相当昂贵的。
问题在于,当您想要反序列化或重新创建一个对象(例如从提交的网页)并更新现有记录时,会出现麻烦。 Linq-to-sql提供的Attach方法只接受以下三种情况:
1. 在所有表上实现时间戳。 2. 重新选择要更改的实体,然后更改并提交。 3. 你巧合地还保留着原始版本的对象。
第一种情况需要进行数据库更改,对于某些环境来说是不可接受的。 第二种情况非常低效-为什么要检索已经拥有的数据? 第三种情况不现实-无状态的Web应用程序通常不会保留历史信息。
重点在于,EF4.0允许您将对象重新附加到ObjectContext并将其标记为已添加或新的,上下文将相应地生成正确的INSERT / UPDATE语句。

4
我经常想到这个问题,因为EF似乎比L2S更加复杂。由于微软正在积极开发EF,因此EF 4的一些新方面可能值得关注。ADO.NET团队博客上有一个很好的摘要,描述了EF的API如何演变以支持更广泛的开发模式。
特别是,我个人对POCO和存储库模式的支持很感兴趣,因为它们非常适合我所在项目。在我看来,使用任何特定提供程序的一个引人注目的原因是未来可以轻松切换到完全不同的提供程序(当然,不需要彻底改变所有应用程序代码)。我认为L2S在这方面缺乏(至少在开箱即用的情况下),我很高兴看到EF 4中的变化。然而,到目前为止,我只是在阅读关于EF 4的这些变化,所以我不能说它们实际上在实践中运行得有多好。

3

EF旨在成为全面的ORM,其中您的对象模型与数据库架构显着不同。L2S更倾向于成为快速的DAL生成器。

问题是EF是一个平庸的ORM,而L2S是一个真正伟大的DAL生成器。

我会说,如果L2S满足您的需求,请继续使用它,不要让微软的营销推动你。如果L2S无法满足您的需求,并且您需要使用微软产品,则选择EF。如果您对技术有些自由度,请考虑NHibernate和LLBGen(在我看来,它们都比EF更好)。


2
他们两个都非常有漏洞。自从一个月前开始使用它以来,我已经在实体框架中发现了8个漏洞(其中两个影响L2S,至少三个仍然存在于EF4中)。这是我生命中最痛苦的经历之一。
如果EF按照他们想要的方式工作,类和表的分离将非常好。

1

当我第一次看到EF时,我就问过自己这个问题,而我已经在Linq2Sql中编写了一个大型应用程序。最大的变化发生在对象映射层。在EF中,关系和导航都是由系统管理的。因此,如果我有两个具有外键关系的表(比如Pets和Owners),我可以执行以下操作:

pet.owner

相比之下,在L2S中我必须自己编写联接查询。如果你有一个“纯联接表”(即只有两个外键而没有其他数据的表),则许多对许多映射会被很好地处理,因为这个表不会在对象映射中表示。

你也可以自己处理急切/延迟加载。

我也可以开发POCOs,所以我不直接绑定框架,即我没有L2S或EF类型的所有噪音干扰,这使得测试更容易。

总的来说,我更喜欢EF,但你的情况可能有所不同。


很棒的回答!不过我有点好奇,我会尝试验证一下,关于pet.owner这个点,我认为在L2S中也是可能的。我可能记错了,我会去查看我曾经这样做的代码。不过你提到的其他点似乎都很有道理,让我思考了起来。 - Refracted Paladin
pet.owner - 可能是 - 我已经有一段时间没有使用它了 - 我需要回去检查一下,也许有人可以确认一下。 - Kevin Jones
3
如果在 Linq to Sql 设计器中两个表之间存在关系,您确实可以通过 pet 对象以这种方式访问并获取 owner - Robert Harvey
@Robert Harvey:谢谢,不过现在我基本上回到了问题的起点...... - Refracted Paladin
-1 这是具有误导性的。如果 L2S 知道您的表关系,则它们会像 EF 一样映射为属性。 - Kirk Broadhurst

0

嗯,最终取决于需求。

现在你使用的是linqtosql,这对你来说是正确的选择,但也许有一天你会有更复杂的需求,可以通过EF更好地实现。例如使用velocity或其他工具。


没有冒犯之意,但你实质上只是在重述我的问题。我明白EF允许更多“复杂性”,但我不明白的是什么? - Refracted Paladin
基本上,你有这三个选择:ORM风格的会话,实体为先的情景和分布式缓存。 - Pablo Castilla

0

如果您希望应用程序在其他DBMS上扩展,Entity Framework具有更好的兼容性,这是其主要优势之一。

Entity Framework将适用于除Microsoft SQL Server之外的其他DBMS,例如Oracle、MySQL等。

而Linq仅限于MS SQL Server。


谢谢你的回答,但是如果你注意到我的原始帖子中写道:“我们总是使用SQL Server作为我们的数据库后端”,所以在这种情况下对我来说并不是一个优点。 - Refracted Paladin

0

1
不再正确。在 EF 4 中,您可以决定是延迟加载还是急切加载。 - Ian Mercer

0

我在一段时间前将所有项目从Linq2Sql转换到Entity Framework。最初,在几个方面上,这是一步退步 - 在Linq2Sql中正常工作的日期表达式在EF中无法正常工作,并且没有延迟加载选项。但是现在,使用Entity Framework 4一切都很顺利。

如果只有你一个人,而且没有时间学习EF,请坚持使用Linq2Sql。但是,如果您有时间并且认为您可能最终需要其他形式的继承,比如-per-table或EF的任何其他功能,请尝试使用它!

而且,您应该转换的#1原因:Entity Framework经验会让您的简历更加出色!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接