LINQ查询与存储过程

时间:2011-01-14 02:49:41

标签: .net sql-server linq linq-to-sql entity-framework

使用linq查询(以及像EF或linq2sql这样的ORM)VS的优点和缺点是什么。存储过程(SQL server 2008)来查询和更新数据模型?性能?速度?等...

13 个答案:

答案 0 :(得分:11)

当您使用代码时,Linq肯定更具可读性。看到调用执行一个名为“sp_GetSomething”的sproc并没有告诉你任何开发人员,除非你去看看sproc的功能。看到像

这样的代码
var query = from c in db.TableName
            where c.Name == "foo"
            select c;

它可以准确地告诉您正在提取的数据。

另一方面,如果您决定更改代码,则存储过程不需要您重新编译应用程序。如果您决定突然更改“where”子句或更改Order By - 更改sproc很容易。更改Linq代码可能会更耗时。

我确信还有更多,但这些是我注意到的两个。

答案 1 :(得分:9)

有2个阵营:用于存储过程和存储过程。

我发现缺乏经验可以让人们走上这样或那样的道路。我们开发的商店种类繁多。

实践中

  • 如果您是公司程序员,那么您永远不会更改您的RDBMS平台。您现在重构您的客户端,并且您将重新实现您的DAL /存储库。为什么?使用存储过程。
  • 如果您为供应商工作,那么您可能需要支持多个RDBMS。 ORM主要抽象出来。

我在公司商店所以......

  • 优点:使用Linq,您不必了解SQL
  • 缺点:当出现问题时你被搞砸了

我们(作为开发人员DBA团队)经常不得不拯救姐妹团队中的ORM用户。

还有更微妙的问题:

  • 任何客户端都可以使用存储过程
  • 将比你的重构更耐用于EF或其他.net 5带来
  • 由存储过程提供的封装来抽象模式
  • 减少了往返次数,因为不应该将存储过程视为方法或原子调用?

答案 2 :(得分:4)

@gbn有一个很好的答案。

在拥有数亿条记录的大型系统中,表示层上的数据操作只是不会削减它。数据密集型应用程序(不是博客应用程序!)需要比您想象的更快地扩展。

在开发中小型系统时,ORM可以节省大量时间。您可以通过正确实施的orm立即拥有生产就绪的应用程序。没有人喜欢写脏话。

记住SQL语法已经存在了20多年也很重要。如果这对你来说并不重要,那么你的编程时间不够长。

答案 3 :(得分:3)

由于以下几个原因,我几乎总是使用存储过程:

1)在代码中使用LINQ查询数据库并不是真正遵循多层体系结构的原则......任何涉及访问数据库对象的事情都应该在数据库级别完成。 LINQ查询只是在代码中编写SQL的包装器。代码中的SQL或LINQ是禁止的,即使MVC示例都是这样做的。

2)性能...存储过程执行得更快!无论何时从代码运行查询,都会出现可伸缩性和性能问题。

3)维护。因为存储过程使您无法在代码中使用SQL或LINQ,所以可以单独处理存储过程的维护(分离关注点)。

答案 4 :(得分:3)

真正的答案是“马匹课程”。从一个角度来看(像@gbn那样的db dev),它一直存储着proc。从我作为后台端到端Web开发人员的角度来看,谁的应用程序的并发使用率从未达到100以上,并且谁在编写高效的SQL方面并不出色,它一直是LINQ(目前是EF 4.1)。代码优先,如果我可以逃脱它。这是我今天在这个问题上读过的第15篇文章(在开发会议上发表争论之后),每一篇文章似乎都提出了同样的建议 - “马匹为课程”。有时候,在后台办公环境中,你不得不考虑数据获取效率 - 你可以快速(有效地)修复错误,以及下一个人如何轻松(有效)地看到你的错误代码正在做。从这个角度来看,LINQ赢得了胜利。

答案 5 :(得分:2)

这取决于您使用的SQL版本。 SQL 2008中的执行计划(SQL使用的信息可以更快地进行第二次调用......)在O / RM中也能很好地工作。 我不明白为什么你会使用O / RM并通过将所有内容重新映射到自定义存储过程来节省大量时间。 还有一个存储过程。很难成为TDD,并且不允许你使用单元的概念和交易

答案 6 :(得分:2)

我同意Peter Lee的观点 - 在一个严肃的企业级环境中,使用存储过程可能是首选方式。

除了彼得的评论之外,还有以下几点:

  1. EF或Linq-to-SQL(或NHibernate)也是ORM,这意味着他们希望将数据库表中的一行转换为对象。由于该对象通常应包含该表中的所有值(或者甚至来自多个表,在EF的情况下),因此这些ORM通常使用SELECT * FROM ....方法。这意味着:由于您选择了所有列,因此通常无法使用任何覆盖索引,并且您的性能会受到影响。这是一种经典的“便利与性能”权衡

  2. 我所知道并且已经使用的所有ORM基本上都需要对基表的完整表访问。对于很多企业和他们的DBA来说,这是一个很大的禁忌。明智地使用存储过程,您可以在不必允许所有用户基表访问的情况下使用 - 这在访问安全性方面是一大优势!

答案 7 :(得分:2)

不是您问题的答案,但不要忘记您仍然可以使用EF on stored procs

答案 8 :(得分:2)

错误的二分法。 IMO,您可以通过使用原始SQL(这是一项我们不应回避的重要技能)使用简单方便的工具来获得两者的最佳位置。存储过程引入了一些大多数人不需要的耦合/部署问题(时间等); ORM可能表现不佳。大多数人都不会改变RDBMS(如果他们这样做,无论如何都会是一个重大的项目),所以:我是参数化命令文本的忠实粉丝。例如,有助于提高工具的工具。

另一位用户发布了一个按名称过滤的LINQ示例;嗯,这里的小巧玲珑:

string name = ...
var list = connection.Query<YourType>(
    "select * from TableName where Name=@name",
    new { name }).ToList();

完全参数化;精心优化;安全;快;清洁;很容易做对。完成工作。

答案 9 :(得分:2)

在回答最初的问题时已经说了很多。我的答案是基于商业方面,而不是技术方面。这是我的经验,也许它会给一些正在开始新项目的人提供一些指示。我们从Asp.net + SQL Server开始,使用大约800个存储过程,应用程序变得复杂。三年来,我们通过微软程序免费使用SQL服务器,所以从未关注过。当超过50K的许可报价达到表格时(基于核心/线程的数量,并且您还需要为从属服务器提供单独的许可证),我们会迁移到MySQL。 希望我们不使用存储过程。如果没有存储过程,我们可以在几天内轻松快速迁移。花了我们更长时间,并努力将SP重写为MySQL。如果您不使用SP,您的应用程序将更灵活/可移植,并且更容易在应用程序本身内调试代码。

因此,如果不是技术性的,从商业角度来看,存在强烈反对在Web应用程序中使用存储过程的情况。如果不使用SP,您还可以将应用程序分发给具有db模式(仅包括表)的客户,同时应用程序逻辑仍隐藏在Linq + EF或Linq SQL中。

答案 10 :(得分:0)

我的偏好是LINQ,检查在像EF Profiler这样的工具中生成的查询。如果任何生成的查询太长或创建N + 1,则通常可以修复它们。一旦投入生产,我会密切关注统计数据,如果缓慢查询无法通过缓存修复,我会将其移至存储过程。

在linq中执行查询的主要优点是:

  • 易于源代码控制和部署查询更改
  • 如果您更改/重命名某些内容,如果您已经破坏某些内容,则会编译查询
  • 可以对您的查询进行单元测试(有可能通过存储过程执行此操作,但我还没有看到有人这样做过)
  • 可以轻松追踪查询的使用位置并删除不再需要的内容

当我加入任何有大量存储过程的项目时,通常会有很多未使用过(或可能没有使用过)的项目,但是没有人敢于删除它们,因为没有人确定。 / p>

我开始使用存储过程的唯一一次是,如果我在公司环境中工作,那么我必须以这样的方式限制对数据库的访问。

答案 11 :(得分:0)

还需要补充一点:使用 TSQL ,您可以创建一个打包的查询,作为单元执行,以确保在您完成查询列表之前,将锁定对行的访问权限。只要我知道我认为无法使用 LINQ

完成
{{1}}

这非常有用 - 例如 - 当您不希望在执行查询列表时执行新插入时。

答案 12 :(得分:-1)

我知道我正在回复一个旧帖子,但是直到今天,事实仍然如此。对于简单的CRUD(创建读取更新删除)过程,没有理由创建存储过程。如果它变得比这更复杂,并且您确实需要利用TSql提供的高级功能,则可以使用存储过程。这应该是两者的均衡组合。