当前位置:  开发笔记 > 编程语言 > 正文

LINQ-to-SQL vs存储过程?

如何解决《LINQ-to-SQLvs存储过程?》经验,为你挑选了13个好方法。

我在StackOverflow(LINQ初学者指南)上看了一下"LINQ 初学者指南",但有一个后续问题:

我们即将推出一个新项目,几乎所有的数据库操作都将是相当简单的数据检索(项目的另一部分已经编写了数据).到目前为止,我们的大多数其他项目都使用存储过程来处理这些事情.但是,如果它更有意义,我想利用LINQ-to-SQL.

所以,问题是:对于简单的数据检索,哪种方法更好,LINQ-to-SQL或存储过程?任何具体的专业人士或骗子?

谢谢.



1> Chris Gillum..:

LINQ优于sprocs的一些优点:

    类型安全:我想我们都明白这一点.

    抽象:LINQ-to-Entities尤其如此.这种抽象还允许框架添加您可以轻松利用的其他改进. PLINQ是向LINQ添加多线程支持的示例.添加此支持的代码更改很少.完成简单调用sprocs的数据访问代码将变得更加困难.

    调试支持:我可以使用任何.NET调试器来调试查询.使用sprocs,您无法轻松调试SQL,并且该体验主要与您的数据库供应商有关(MS SQL Server提供了查询分析器,但通常这还不够).

    供应商不可知:LINQ适用于大量数据库,支持的数据库数量只会增加.由于语法或功能支持不同(如果数据库完全支持sprocs),Sprocs并不总是在数据库之间移植.

    部署:其他人已经提到过这一点,但部署单个程序集比部署一组sprocs更容易.这也与#4联系在一起.

    更简单:您不必学习T-SQL来进行数据访问,也不必学习调用sprocs所需的数据访问API(例如ADO.NET).这与#3和#4有关.

LINQ vs sprocs的一些缺点:

    网络流量:当LINQ发送整个查询时,sprocs只需要通过线路序列化sproc-name和参数数据.如果查询非常复杂,这可能会非常糟糕.但是,LINQ的抽象允许微软随着时间的推移改进这一点.

    灵活性较差:Sprocs可以充分利用数据库的功能集.LINQ在它的支持中往往更通用.这在任何类型的语言抽象中都很常见(例如C#与汇编程序).

    重新编译:如果需要更改数据访问方式,则需要重新编译,版本和重新部署程序集.Sprocs 有时可以允许DBA调整数据访问例程,而无需重新部署任何内容.

安全性和可管理性也是人们争论的问题.

    安全性:例如,您可以通过直接限制对表的访问来保护敏感数据,并将ACL放在sprocs上.但是,使用LINQ,您仍然可以限制对表的直接访问,而是将ACL放在可更新的表视图上以实现类似的结束(假设您的数据库支持可更新视图).

    可管理性:使用视图还可以使您的应用程序不受模式更改(如表规范化)的影响.您可以更新视图,而无需更改数据访问代码.

我曾经是一个大家伙,但我开始倾向于LINQ作为一般的更好的选择.如果有一些区域的sprocs显然更好,那么我可能仍然会编写一个sproc但是使用LINQ访问它.:)


"LINQ适用于大量数据库"但LINQTOSQL仅支持SQL Server.
除了MSSQL之外,LINQ to Entities还可以与Postgres和MySql一起使用.不确定,但我以为我读过有关Oracle的东西.
我没有看到有人提到代码重用.你不能在VB6或asp或文件制作专业应用程序中重用你的linq.如果你在数据库中放了一些东西,它就可以在任何地方重复使用.你可以使用linq制作一个dll我想但是这变得过于复杂和糟糕的imo.添加可重用的函数或存储过程要简单得多.

2> Eric Z Beard..:

由于DBA多年来一直在努力的所有原因,我通常支持将所有内容都放在存储过程中.对于Linq,确实与简单的CRUD查询没有性能差异.

但在做出这个决定时要记住一些事项:使用任何ORM将您紧密地联系到您的数据模型.DBA无法自由更改数据模型,而无需强制更改已编译的代码.使用存储过程,您可以在一定程度上隐藏这些类型的更改,因为从过程返回的参数列表和结果集表示其合同,并且只要合同仍然满足,就可以更改内部条件. .

而且,如果Linq用于更复杂的查询,调整数据库将变得更加困难.当存储过程运行缓慢时,DBA可以完全专注于代码,并且有很多选项,这样只要合同在他/她完成时仍然满足.

我已经看到很多很多情况,通过更改存储过程中的模式和代码来解决应用程序中的严重问题,而不会对已部署的已编译代码进行任何更改.

也许一个混合方法对Linq来说会很好吗?当然,Linq可用于调用存储过程.


我必须说我已经看到了关于紧密耦合到数据库的争论,我并不确定它是否有效.我从来没有真正遇到过一种情况(超出一些简单的例子),我想要更改数据库,无论如何都不需要更高代码.实际上,无论如何,Linq与存储过程或参数化查询有何不同.无论您使用ORM还是更简单的东西,您的数据访问层仍应很好地分离和抽象.这就是为什么会给你松耦合,而不是你使用的技术.只是我的2c
"DBA无权自由地更改数据模型,而无需强制更改已编译的代码." 你为什么要提倡这个?没有人应该有"自由"来做出改变,这就是配置管理的重点.无论如何,更改都应在部署之前通过dev,test等进行.
您忽略的一个功能是安全性.使用Linq,您必须将表直接公开给应用程序.使用存储过程,您可以限制对这些过程的访问并强制执行您的业务要求.
我见过的SP的使用199这是从应用程序由SP签名的方式屏蔽每1个架构更改不必要编写的存储过程,但类似什么西蒙P史蒂文斯说,语义变化所需的应用程序更改的100%时间无论如何.更不用说SP的存在只是乞求一些未来的dev或dba将一些业务逻辑泄漏到SP中.然后多一点,多一点.
@Neil:是的,但是如果不强迫开发人员更改代码,他就无法在开发环境中进行更改.
@Eric - 很棒的评论.我是开发人员和DBA.我戴着两顶帽子用于咨询目的,并提倡相同的.LINQ有它的位置,它不会取代SP.增强的是小型项目/团队将产品推向市场的能力.但是公司/项目变得越来越大并且必须适应高可用性,VLDB,调整,提示,复杂查询等等的日子将会很少.在我的大批量,高可用性解决方案中,我永远无法使用Linq .特别是当有程序员团队和DBA合作提供强大的解决方案时.
@Chris:您所说的安全问题可以使用视图和角色轻松解决.

3> Keith..:

Linq到Sql.

Sql server将缓存查询计划,因此sprocs没有性能提升.

另一方面,您的linq语句将在逻辑上与您的应用程序一起进行测试.Sprocs总是有点分开,难以维护和测试.

如果我现在正在从头开始研究一个新的应用程序,我会使用Linq,没有sprocs.


关于你对sprocs没有收获的评论,我不同意.我在prod系统上描述了一系列SQL Server访问方法,并且使用Prepare + stored procs获得了最好的结果.甚至跨越多个相同逻辑的调用.但是,对于低使用率的DB,你可能也是对的.
@RussellH:.Net 3.5就是这样,他们在.Net 4中修复了这个问题(适用于L2S和L2E)
@Kieth不是这样的!Linq创建了比SP更多的执行计划.调试代码存在诸多好处; 但是重新编译公司部署周期的问题; 测试不同的ACTION查询,WHERE,ORDER BY的不灵活性.更改WHERE语句的顺序可能导致处理不同的查询; 预取; 这在Linq中不容易做到.需要将数据层用于调整.SP更难维护和测试?如果你不习惯它; 但SP对于军团和VLDB,高可用性等都是有益的!Linq是小型项目,单独工作; 去吧.
@SnapJag - 你说得对,sprocs可以让你获得更好的颗粒控制,但事实是99%的时间(即使在我工作的大型企业系统中)你不需要任何额外的优化.Sprocs很难维护和测试你是否习惯了它们 - 我已经习惯了它们(在我是开发人员之前我是一名DBA)并且确保每个CRUD操作的sproc用于不同表的负载是最新是一种痛苦.最佳实践(IMHO)是以最简单的方式编码,然后运行性能检查并仅在需要时进行优化.

4> lomaxx..:

对于基本数据检索,我会毫不犹豫地去找Linq.

自从搬到Linq后,我发现了以下优点:

    调试我的DAL从未如此简单.

    当架构更改无价时,编译时间安全性.

    部署更容易,因为所有内容都编译成DLL.不再管理部署脚本.

    因为Linq可以支持查询实现IQueryable接口的任何内容,所以您将能够使用相同的语法来查询XML,对象和任何其他数据源,而无需学习新的语法


部署不需要通过QA的SQL脚本在这里不一定是件好事.

5> SQLMenace..:

LINQ将膨胀程序缓存

如果应用程序正在使用LINQ to SQL并且查询涉及使用长度可变的字符串,那么对于每个可能的字符串长度,SQL Server过程高速缓存将变得臃肿.例如,考虑针对AdventureWorks2008数据库中的Person.AddressTypes表创建的以下非常简单的查询:

var p = 
    from n in x.AddressTypes 
    where n.Name == "Billing" 
    select n;

var p = 
    from n in x.AddressTypes 
    where n.Name == "Main Office" 
    select n;

如果同时运行这两个查询,我们将在SQL Server过程高速缓存中看到两个条目:一个绑定NVARCHAR(7),另一个绑定NVARCHAR(11).现在想象一下,如果有数百或数千个不同的输入字符串,都有不同的长度.对于完全相同的查询,过程高速缓存将不必要地填充各种不同的计划.

更多信息:https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?反馈ID = 363290


SQLMenace:根据您链接的页面,问题在VS2010中得到解决.
多么愚蠢的论点 - 只需使用一个变量就可以解决问题.
这个问题在发布答案时有效,但从那时起它已经在VS2010中得到解决,因此不再是问题.
@John,如果您使用了验证而不是文字字符串,那将无济于事,因为最后您将文字字符串发送到数据库.它可能看起来像代码中的变量,但它将是生成的T-SQL中的一个字符串,它将被发送到数据库.

6> Dr8k..:

我认为专业LINQ论证似乎来自那些没有数据库开发历史的人(一般而言).

特别是如果使用VS DB Pro或Team Suite等产品,此处提出的许多参数都不适用,例如:

更难以维护和测试:VS提供完整的语法检查,样式检查,参考和约束检查等.它还提供完整的单元测试功能和重构工具.

LINQ使真正的单元测试变得不可能,因为(在我看来)它没有通过ACID测试.

LINQ中的调试更容易:为什么?VS允许从托管代码完全步入并定期调试SP.

编译成单个DLL而不是部署脚本:再次,VS可以构建和部署完整数据库或进行数据安全的增量更改.

不必用LINQ学习TSQL:不,你不需要,但你必须学习LINQ - 哪里有好处?

我真的不认为这是一种好处.能够孤立地改变某些东西在理论上听起来不错,但仅仅因为改变履行合同并不意味着它正在返回正确的结果.为了能够确定正确的结果是什么,您需要上下文,并从调用代码中获取该上下文.

嗯,松散耦合的应用程序是所有优秀程序员的最终目标,因为他们确实提高了灵活性.能够孤立地改变事物是很棒的,而且你的单元测试将确保它仍然能够返回适当的结果.

在你们都感到不安之前,我认为LINQ有它的位置并且有一个美好的未来.但对于复杂的数据密集型应用程序,我认为它不准备取代存储过程.这是我今年在TechEd的一个MVP回应的观点(他们将保持无名).

编辑:LINQ to SQL存储过程方面的东西是我仍然需要阅读更多 - 取决于我发现我可能会改变我的上述dia骂;)


同意!许多人(开发人员)正在寻找小型团队和项目的"快速上市"解决方案.但是,如果使用多个团队,大型数据库,高容量,高可用性,分布式系统将开发推进到下一级企业风格,那么使用LINQ将是另一回事!我不相信你需要在很长一段时间内编辑你的意见.LINQ不适用于规模较大且拥有多人,多个团队(Dev&DBA),并且具有严格部署计划的项目/团队.
学习LINQ没什么大不了的 - 它只是语法糖.TSQL是一种完全不同的语言.苹果和橘子.
学习LINQ的好处在于它不依赖于单一技术 - 查询语义可以用于XML,对象等,并且这将随着时间的推移而扩展.

7> 小智..:

LINQ是新的,有它的位置.LINQ不是为了替代存储过程而发明的.

在这里,我将重点介绍一些性能神话和CONS,仅用于"LINQ to SQL",当然我可能完全错了;-)

(1)人们说LINQ语句可以在SQL服务器中"缓存",因此它不会失去性能.部分正确."LINQ to SQL"实际上是将LINQ语法转换为TSQL语句的运行时.因此从性能角度来看,硬编码的ADO.NET SQL语句与LINQ没有区别.

(2)举一个例子,客户服务UI具有"帐户转移"功能.此函数本身可能会更新10个DB表并一次性返回一些消息.使用LINQ,您必须构建一组语句并将它们作为一个批处理发送到SQL服务器.这个翻译的LINQ-> TSQL批处理的性能很难与存储过程相匹配.原因?因为您可以使用内置的SQL分析器和执行计划工具调整存储过程中语句的最小单元,所以不能在LINQ中执行此操作.

关键是,当谈论单个DB表和小数据集CRUD时,LINQ与SP一样快.但是对于更复杂的逻辑,存储过程可以更好地调整性能.

(3)"LINQ to SQL"很容易让新手介绍性能值.任何高级TSQL人都可以告诉你何时不使用CURSOR(基本上你不应该在大多数情况下在TSQL中使用CURSOR).使用LINQ和带有查询的迷人"foreach"循环,新手很容易编写这样的代码:

foreach(Customer c in query)
{
  c.Country = "Wonder Land";
}
ctx.SubmitChanges();

你可以看到这个简单得体的代码是如此吸引人.但在幕后,.NET运行时只是将其转换为更新批处理.如果只有500行,这是500行TSQL批次; 如果有数百万行,这是一个打击.当然,有经验的用户不会用这种方式来完成这项工作,但重点是,这样很容易.


使用C/C++/C中的指针很容易失败#这是否意味着永远不应该使用它?

8> Mark Cidade..:

最好的代码是没有代码,并且对于存储过程,您必须在数据库中编写至少一些代码并在应用程序中编写代码来调用它,而使用LINQ to SQL或LINQ to Entities,您不必编写任何其他代码除了实例化上下文对象之外,代码超出任何其他LINQ查询.



9> 小智..:

LINQ绝对在特定于应用程序的数据库和小型企业中占有一席之地.

但在大型企业中,中央数据库充当许多应用程序的通用数据中心,我们需要抽象.我们需要集中管理安全性并显示访问历史记录.我们需要能够进行影响分析:如果我对数据模型进行一些小改动以满足新的业务需求,需要更改哪些查询以及需要重新测试哪些应用程序?观点和存储过程给了我这个.如果LINQ可以做到这一切,并使我们的程序员更高效,我会欢迎它 - 有没有人有在这种环境中使用它的经验?


你提出了一个好点; 在这种情况下,LINQ不是替代方案.

10> lomaxx..:

DBA无法自由更改数据模型,而无需强制更改已编译的代码.使用存储过程,您可以在一定程度上隐藏这些类型的更改,因为从过程返回的参数列表和结果集表示其合同,并且只要合同仍然满足,就可以更改内部条件. .

我真的不认为这是一种好处.能够孤立地改变某些东西在理论上听起来不错,但仅仅因为改变履行合同并不意味着它正在返回正确的结果.为了能够确定正确的结果是什么,您需要上下文,并从调用代码中获取该上下文.



11> 小智..:

恕我直言,RAD = LINQ,RUP =存储过程.我在一家大型财富500强公司工作了很多年,包括管理层在内的许多层面,坦率地说,我绝不会聘请RUP开发人员来开发RAD.它们是如此孤立,以至于他们对在该过程的其他层面上做什么的知识非常有限.对于孤立的环境,让DBA通过非常具体的入口点控制数据是有意义的,因为其他人坦言不知道完成数据管理的最佳方法.

但大企业移动痛苦地在发展领域缓慢,这是极其昂贵的.有些时候你需要更快地移动以节省时间和金钱,LINQ提供了更多的功能.

有时我认为DBA对LINQ有偏见,因为他们认为这会威胁到他们的工作安全.但这就是野兽的本质,女士们,先生们.


是的,我们DBA坐在那里等待你要求Stored Proc推进生产.不必这样做会打破我们的心!

12> 小智..:

我认为你需要使用procs来获得任何真实的东西.

A)在linq中编写所有逻辑意味着您的数据库不太有用,因为只有您的应用程序可以使用它.

B)我不相信对象建模比关系建模更好.

C)在SQL中测试和开发存储过程比任何Visual Studio环境中的编译编辑周期快得多.你只需编辑,F5并点击选择即可参加比赛.

D)管理和部署存储过程比组件更容易..你只需将文件放在服务器上,然后按F5 ...

E)Linq to sql仍然会在你不期望的时候编写糟糕的代码.

老实说,我认为MS的最终目的是增加t-sql,以便它可以像linq那样隐含地进行连接投影.例如,t-sql应该知道你是否想要订购order.lineitems.part.



13> kenny..:

LINQ不禁止使用存储过程.我使用了LINQ-SQL和LINQ-storedproc的混合模式.就个人而言,我很高兴我不必编写存储过程.... pwet-tu.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有