您将如何评价每一个方面的:
性能
发展速度
简洁、直观、可维护的代码
灵活性
总体
我喜欢我的SQL,因此一直是ADO.NET和存储过程的铁杆粉丝,但我最近玩了一个从LINQ到SQL的游戏,被我写数据访问层的速度搞得晕头转向,并决定花些时间真正了解LINQ到SQL或EF…或者两者都不是?
我只是想检查一下,这些技术中没有什么大缺陷会使我的研究时间变得无用。例如,性能很糟糕,对于简单的应用程序来说很酷,但只能带你走这么远。
更新:你能专注于EF vs L2S vs SP而不是ORM vs SP吗?我主要对ef和l2s感兴趣,但我也希望将它们与存储过程进行比较,因为我对纯SQL了解很多。
- 不是建设性的,但是有那么多赞成票?…;)
- 我不明白为什么有人认为这不是建设性的。我觉得很好。比我高1。
- 在我看来,这是一个很好的问题。就我个人而言,我注意到实体框架和所有类似的窗体都比普通/简单的ADO.NET代码慢。我两年前做过这个测试,一周前又做了一次。我不确定Linq to SQL与EF的比较情况。但是ADO.NET将永远是性能最好的。如果您想节省开发时间,那么实体框架是一个很好的工具,但在性能是您主要关注的问题时绝对不是。
- @lukled现在使用较少存储过程的原因是什么?
- @永恒:不依赖数据库机制是一种趋势。每个数据库引擎都有自己的存储过程语言,因此还有额外的学习。99.9%的开发人员可以依赖于ORM,它可以生成相当好的代码并自动创建SQL。对于简单的积垢,性能差异是微乎其微的。存储过程很难开发和维护。几年前,当没有窗体时,数据库就不会神奇地自动生成任何内容。编写SP被认为不太费时,因为它是在应用程序中编写SQL语句的替代方法。
- @Sunil是正确的,虽然不够冗长。问题是每个人都认为他们最关心的是应用程序的性能。当我谈到需要顶级性能的应用程序时,我想到的是HydC++MMO或高容量的面向客户的数据库事务。您真的应该关注面向对象的原则,比如可维护性、可读性、持久性无知和域逻辑分离。尤其是在许多情况下,性能的提高充其量很小或根本不存在时。
- 这个问题对我很有用。这是一个建设性的问题,可能会提供非常有用的信息。StackOverflow社区也不应该认为这不是我的建设性+1。
- 看看weblogs.asp.net/fbouma/…
首先,如果您正在启动一个新项目,请使用实体框架("ef")—它现在生成了更好的SQL(更像Linq to SQL那样),并且比Linq to SQL("L2s")更易于维护和更强大。随着.NET 4.0的发布,我认为Linq to SQL是一种过时的技术。微软一直非常开放,不继续L2S的进一步发展。
1)性能
这很难回答。对于大多数单实体操作(CRUD),您将发现这三种技术的性能几乎相同。您必须知道ef和linq-to-sql是如何工作的,才能充分利用它们。对于诸如轮询查询之类的大容量操作,您可能希望让EF/L2S"编译"您的实体查询,这样框架就不必不断地重新生成SQL,或者您可能会遇到可伸缩性问题。(参见编辑)
对于正在更新大量数据的批量更新,原始SQL或存储过程将始终比ORM解决方案执行得更好,因为您不必通过连接到ORM的线路编组数据来执行更新。
2)发展速度
在大多数情况下,当涉及到开发速度时,EF将吹走裸SQL/存储过程。EF设计器可以在模型更改时(根据请求)从数据库中更新模型,因此不会在对象代码和数据库代码之间遇到同步问题。唯一一次我不会考虑使用ORM的时候是你在做一个报告/仪表板类型的应用程序,你不做任何更新,或者你创建一个应用程序只是为了对数据库进行原始数据维护操作。
3)整洁/可维护的代码
动手,ef胜过sql/存储过程。因为您的关系是建模的,所以代码中的连接相对较少。对于大多数查询,实体之间的关系对于读者几乎是不明显的。没有什么比从一层到另一层调试或通过多个SQL/中间层来了解数据实际发生了什么更糟糕的了。EF以一种非常强大的方式将数据模型引入到代码中。
4)柔韧性
存储过程和原始SQL更加"灵活"。您可以利用存储过程和SQL为奇怪的特定情况生成更快的查询,并且可以比使用和ORM更容易地利用本机DB功能。
5)总体
不要陷入选择ORM和使用存储过程的错误二分法中。您可以在同一个应用程序中同时使用这两种方法,而且您可能应该这样做。大批量操作应该放在存储过程或SQL(实际上可以由EF调用)中,而EF应该用于CRUD操作和大多数中间层的需要。也许您会选择使用SQL编写报告。我想这个故事的寓意和以前一样。使用正确的工具进行作业。但是,现在的ef非常好(从.NET 4.0开始)。花一些时间深入阅读和理解它,你可以轻松地创建一些惊人的高性能应用程序。
编辑:EF5使用自动编译的LINQ查询简化了这一部分,但是对于真正的大容量的东西,您肯定需要测试和分析什么最适合您在现实世界中。
- 绝对精彩的回答。我现在确实在使用EF来快速开发应用程序。如果性能成为一个问题,存储的过程将被引入以重构性能不佳的EF查询。谢谢!
- @BritishDeveloper:另外,不要忘记使用视图的强大功能。在我们的L2S项目中定义了两个视图,并在框架似乎编写糟糕查询的地方利用它们,我们取得了巨大的成功。这样,我们就获得了使用框架的所有好处,以及编写自己的SQL的所有好处。
- 我也在使用视图;)更多地是为了解决EF的非交叉数据库限制。不过,这是用于优化的好主意。谢谢
- 肯定是个很好的回应。只是想增加一个观察,我在我自己的经验与L2S与EF4。当我们意识到我们可能正在使用几个不同的RDMBS后,从L2S->EF4交换…但是,在运行MSSQL的同时,性能下降主要表现在我的应用程序的GUI区域。数据绑定到L2S中的结果集比EF4快得多。这是对完全相同的数据库的完全相同的查询。不过,这里需要注意的一点是,我将返回90K以上的记录,所以差异非常明显。也许在较小的场地上,这不是问题?不知道它会如何扩展,尽管有大量的网站…
- 反应良好。我刚刚花了4周时间与linq-to-entities一起工作,试图将所有内容都导入其中,最后才意识到您需要使用本机SQL来进行批量复制、批量删除、从数据库中快速删除重复项等操作。使用正确的工具来完成此项工作,将本机SQL与linq-to-entities框架混合并不羞耻。
- 英孚的使用和保存更好。代码优先是.NET所缺少的。对于复杂的场景,我会使用SQL,对于其他几乎所有的场景,我都会使用EF。如果某个特定项存在任何性能问题,只需测试该项并检查它是否是源代码,如果它确实是ef,则改为纯SQL。提示:如果可能的话,将您的SQL字符串保存在一个类中,并且只引用它们(因此您只需更改一次SQL,并避免重复编码和全部更改)。
- 这是我最喜欢的一句话:"我唯一一次不考虑使用ORM的是,当您在执行报告/仪表板类型的应用程序时,您没有进行任何更新",我构建复杂的报告和仪表板,以供生活在第三方数据库中,我们不允许为其编辑任何数据,但可以添加我们自己的报告存储过程。ORM对于这种类型的应用程序开发没有任何意义,所以我很高兴看到这里提到的它并不适合。
存储过程:
(++)
(-)
- 需要SQL知识
- 存储过程不受源代码管理
- 在指定相同的表和字段名时,大量的"重复您自己"。在重命名一个数据库实体并在某个地方缺少对它的一些引用后,破坏应用程序的可能性很高。
- 发展缓慢
ORM:
(+)
- 快速发展
- 数据访问代码现在受源代码控制
- 您与数据库中的更改隔离开来。如果发生这种情况,您只需要在一个位置更新模型/映射。
(-)
- 性能可能更差
- 没有或很少控制ORM产生的SQL(可能效率低下或更糟)。可能需要干预并用自定义存储过程替换它。这将导致代码混乱(代码中的一些LINQ、代码中的一些SQL和/或源代码控制之外的数据库)。
- 因为任何抽象都可以产生"高层次"的开发人员,他们不知道它在引擎盖下是如何工作的。
一般的折衷办法是在拥有很大的灵活性和大量的时间损失之间,而不是在你能做的事情上受到限制,而是让它很快完成。
这个问题没有一般的答案。这是圣战的问题。还取决于手头的项目和您的需求。挑选最适合你的。
- 我不认为有关源代码管理的要点是相关的。数据库模式、存储过程、UDF等都可以并且应该受源代码管理。
- +1用于As any abstraction can produce"high-level" developers having no idea how it works under the hood。
- 同意,源代码管理参数不正确。我们总是将数据库创建脚本存储在SVN中。在开发数据库应用程序时,如何将数据库保持在源代码管理之外?
- EF不太适合高可用性和高性能,我不是DBA,但我不知道EF提供了什么,这使得代码编写更容易。
- 因此,我们将放弃灵活性、完全控制和性能,以实现"快速开发",并避免在数据库发生变化时更改代码。对我来说,这听起来像是纯粹的懒惰。
- 我同意源头控制的论点可能不成立…我目前在Visual Studio中的一个SQL项目中维护我的数据库结构,因此每当我对任何脚本文件进行任何更改时,我只需单击"将更改发布到SQL Server中的数据库",并将更改推送到Git repo。
您的问题基本上是O/RM与手写SQL
使用ORM还是纯SQL?
看看其他一些O/RM解决方案,L2S不是唯一的解决方案(NHibernate、ActiveRecord)
http://en.wikipedia.org/wiki/list_object-relational_mapping_软件
要解决具体问题:
根据O/RM解决方案的质量,L2S非常擅长生成SQL
一旦你摸索这个过程,使用O/RM通常会快得多。
代码通常也更整洁,更易于维护。
直接SQL当然可以让您获得更大的灵活性,但是大多数O/RM可以执行除最复杂的查询之外的所有操作。
总的来说,我建议使用O/RM,灵活性损失是可以忽略的。
- @大卫,谢谢,但这不是ORM和SQL。我想搬到ORM去,想知道该把时间花在学习上:ef或l2s(除非它们与存储的过程相比是垃圾)
- 我肯定会说,与存储过程相比,它们不是垃圾,而且附带的好处是您没有将代码传播到数据库中。就我个人而言,我喜欢L2S,但我在这一点上对EF做得不多,似乎L2EF将取代它,所以我会选择EF。而且,一旦你去了林肯,你就不会回去了。
LinqtoSQL是一项非常简单的技术,大体上,它可以为后端生成非常好的查询。linq-to-ef计划取代它,但从历史上看,它的使用极其笨拙,生成的SQL质量也差得多。我不知道目前的情况,但微软承诺将L2S的所有优点迁移到L2EF,所以现在可能会更好。
就我个人而言,我对ORM工具有着强烈的反感(详情请参阅我在这里的评论),因此我认为没有理由支持L2EF,因为L2S提供了我从数据访问层所期望的一切。事实上,我甚至认为L2S特性(如手工制作的映射和继承建模)添加了完全不必要的复杂性。但那只是我。;-)
- L2S相当不错,但它的缺点是微软已经声明他们基本上不会在扩展它方面投入太多资金。您可以在最新版本中看到这一结果,该版本只修复了一些错误,并添加了一些对SQL Server 2008数据类型的支持。
- 同意,@finnnk.这是一个不幸的现实,使用L2S有点危险,因为它的贱民地位。但是,如果他们真的完全支持L2EF,我强烈怀疑会有一个迁移路径,因为它仍然享受以下。
- linq-to-ef已经成熟,现在可以生成和l2s一样好的SQL(从.NET 4.0开始)。现在,L2EF比L2S要好得多,因为它至少可以随着数据库的变化而更新您的模型,而L2S永远不会自动更新模型。我还喜欢这样一个事实,即您可以将简单的m:m关系与ef映射为关系,而无需具有中间实体。它使代码更加清晰。
- 谢谢你的更新@dave。不过,我不同意M:M的评论。我使用的模式几乎总是在联接表上增加额外的属性。这导致了对象模型的结构变化,需要大量的代码返工。我宁愿从一开始就明确地处理中间关系。
如果您所追求的是存储过程的功能和性能,以及实体框架等工具提供的快速开发,那么您可能需要考虑一种全新的方法。
我用SQL+在一个小项目上进行了一次测试,它真的很特别。基本上,您可以向SQL例程添加相当于注释的内容,这些注释向代码生成器提供指令,然后根据实际的SQL例程构建一个非常好的面向对象类库。有点像反向的实体框架。
输入参数成为输入对象的一部分,输出参数和结果集成为输出对象的一部分,服务组件提供方法调用。
如果您希望使用存储过程,但仍然希望快速开发,那么您可能需要看看这些东西。