2009-04-07 61 views

回答

5

LINQ是.Net框架的一个很好的补充,但是它确实有它的局限性。到目前为止,LINQ还不支持所有的SQL语法(尽管我确定他们正在处理它)。而且,对于LINQ来说,处理多个表格并且只给我们需要的数据并没有干净的方式。有了LINQ,你必须检索所有的数据,然后保留你想要的,并把剩下的部分扔掉,从而传输比实际需要更多的数据,这是一个性能问题。

如果你正在做的只是简单的INSERT,UPDATE和DELETE语句LINQ是走的路(在我看来),所有的优化都是为你完成的,对于更复杂的工作,我会说坚持存储程序。

+2

实际上,由于查询执行是延迟的,只要您在中间不做类似ToArray的事情,它会正确处理连接,并让数据库执行最佳操作。如果你在谈论行宽,你总是可以使用匿名对象,它会做出正确的选择。 – 2009-04-07 18:41:32

+0

是的,同意 - 你当然可以限制通过LINQ将数据拉回到非常详细的级别。 – 2009-08-10 19:43:36

+0

erm ... LINQ是查询,而不是插入,删除或任何其他 – BlackTigerX 2011-09-28 19:20:02

2

我假设你的意思是LINQ to SQL作为LINQ和存储过程是两个非常不同的东西。

使用任何ORM的主要原因之一是提高开发速度。只要你有一个组件会为你创建查询,那么你就必须自己编写一个组件。

4

从我的角度来看,使用LINQToSQL消除了存储过程的主要价值。很长一段时间,使用存储过程的关键在于将SQL封装在自然使用参数化查询的形式中。这为开发人员提供了一个关于SQL注入的安全层。由于LINQToSQL查询默认情况下是参数化的,我发现我对存储过程的使用大大减少了。

这并不是说他们还没有一席之地,但现在我觉得只有在他们为参数化的LINQ查询提供重要价值时,才应该使用它们,这可能是因为复杂性较低或性能提高,这可能是因为的服务器的能力,以优化程序。我觉得,除去对存储过程的依赖,会产生更易维护的代码库,因为大多数代码都位于IDE中,而不是在数据库和IDE之间进行拆分。

请注意,您仍然可以在LINQToSQL中使用存储过程。我只是没有发现这么做的价值。实际上,我不能想到自从切换到LINQToSQL以来编写的单个存储过程,尽管我已经编写了几个表值函数来执行特定的搜索。这些被放到我的DataContext上,并显示为我可以调用的方法,以使用该函数从数据库中获取适当的实体。

+0

LINQ to SQL的安全性仍然差得很远,因为您必须在表级授予访问权限,而您不必使用正确书写的特效程序。你可能会从外面保护OK,但是你会让内部人员在你的系统中发生欺诈行为。 – HLGEM 2009-04-07 21:58:35

+0

区别在于我通过角色控制应用程序级别的访问,而不是在数据库级别。没有人可以使用自己的凭据进行访问。所有访问都通过LINQToSQL数据上下文的权限层进行过滤。 – tvanfosson 2009-04-08 01:07:52

10

因为没人加了CON - 我会建议一个在这里...

存储的特效为您提供拒绝选择/插入/在你的基表和视图删除/更新的能力,所以你可以有潜在的使用存储过程更好的安全性,因为您可以使用Linq to SQL。通过仅授予您的特许权使用权限,您可以使用较小的表面积来管理安全性。

当然 - 你仍然可以使用Linq到SQL和存储过程一起 - 也许这将是更好的选择。

+0

+1打我,这就是我正在输入的内容... – 2009-04-07 18:17:38

+0

我刚才说过,但我的罗嗦。 :) – 2009-04-07 19:20:16

+0

这可能是更多的PRO存储过程比真正的CON的LINQ。它是控制资源授权的又一层。但是这也可以在其他层完成,例如,应用程序,我们并不是说存储过程的一个*缺点是它们不能访问例如ASP.NET安全API,尽管C#。 – 2012-01-05 08:11:43

1

我前几天正在和某人讨论这个问题,因为我们目前对所有数据库访问都使用存储过程。我们一般在讨论LINQ,以及LINQ to SQL实现,IQueryable等。她很快意识到,使用LINQ和sprocs在最坏情况下是多余的,而且很难。

LINQ to SQL的优点在于代码存在于一个地方,而且数据库中发生的事情非常清楚。此外,开发时间可能会更少,主要取决于流程,因为要制作的工作产品更少。

Sprocs的优点,正如我所见,也是双重的。存储过程为DBA提供了更好的访问控制,因为他们可以在部署之前检查存储过程,并允许应用程序只使用访问权限来执行该存储过程,而不是读/写所有需要的表。这可以更好地评估数据库争用和性能问题。我看到的另一个好处是,虽然LINQ to SQL将生成正确的查询,但在复杂查询的情况下,有时您会遇到导致数据库端优化不佳的情况。在这些情况下,您要么重写查询,要么向优化器提供提示,这两者都很难/不可能/隐喻与LINQ打破。

也许是在我的DBA(不是DBA,但已经),但在一个大型高的事务负载DB工作,不知道会由系统执行的每一个可能的声明正是时候我觉得真的很紧张。所以我坚持自己的sprocs。

0

我在我的项目中广泛使用了LINQ-to-SQL,并且几乎在所有情况下都发现它的性能与SP相当。

有些情况下,您使用LINQ到SQL失去性能/能力,毫无疑问:

  • 由于查询使用LINQ代码包裹起来,你不能使用SQL的内置查询优化器/索引优化器工具(如同轻松)。像追踪执行计划的事情也需要一个额外的步骤(获得生成的SQL)。我觉得很琐碎。

  • 如果你有一个非常低的带宽情况,通过线路发送参数化查询的额外文本会消耗更多的带宽,而不仅仅是发送存储过程调用。因此,如果您正在编写一个通过调制解调器连接进行通信的Windows应用程序,这可能比Web应用程序(服务器彼此相邻)更令人担忧,或者如果您处于非常高的使用情况。

3

有几件事情我想补充的讨论:

  • 的LINQ是不太可能打在SQL Server中的高速缓存的执行计划不是一个存储过程。虽然编译基本选择语句很简单,但在更复杂的查询编译中可能会非常昂贵。 (很多因素会影响您的情况的声明是真/假,但这可能适用于其他帖子)。

  • 如果您有歪斜的数据重新编译可能实际上是一个好处,防止SQL的奇数索引使用决策。认为select * FROM Person where LastName = @Letter首先通过@Letter='Z'(可以说占总人数的0.25%)与@Letter='S'(占总人数的6.00%)可以产生截然不同的执行计划。

  • Linq正在有效地将ad hoc sql重新引入到我们的代码中。通过一个抽象层和一种新的语言来授予它,但我不再打电话给exec GetOrders @[email protected] @DayRange=7,而是写出我的表名,where子句和order by。

  • 将非高性能SQL语句跟踪到生成语句的代码比使用SP更加困难。在高容量环境中,SQL分析器通常定期运行以查找非高性能查询(高CPU,读取或持续时间)。由于Linq抽象了它生成的文本,因此很难将sql追溯到代码中的特定位置,特别是在较大的应用程序中。

  • 作为一个便笺,必要时Linq可以调用特定的存储过程而不是生成它自己的SQL。看到这个Scott Gu article

+0

至于“Linq不太可能命中缓存执行计划”:我发现由LINQ生成的查询更可能为每个查询生成多个计划 - 虽然这需要一些时间为了“缓存”新服务器,生成的计划更加专业化,从而经常提高性能。 – NTDLS 2012-08-03 14:26:57

+0

@NTDLS - 我同意的大部分。自从我写这个以更好地符合您的观点以来,Linq查询生成已经发展。更多(更具体)的计划*可以*提高性能 - 它们*还可以*降低性能。在足够大/变量足够的系统中,太多计划可能导致缓存清理以释放资源,导致缓存的查询计划点击次数减少。另外,在我的声明中隐含的是,在SQL 2008中,我可以固定'正确的'SP执行计划,并避免数据和参数嗅探可能产生的缺陷。我想这就是为什么我在这一点上放了一个免责声明。 – EBarr 2012-08-03 14:45:21

1

我不明白为什么关于这个主题的每一个讨论似乎都假设写SQL是困难的,而写linq查询却不是。尽管简单的linq的确如此简单,但只要你想编写一个访问大量表的查询,并且使用复杂的外连接,它就变得非常混乱。不仅如此,我不知道底层引擎如何呈现我的查询,如果它不起作用,则很难调试。

我发现它比使用linq做同样的事情要容易100倍,能够快速编写一个复杂的SQL语句(当然,我也是这样成长起来的,但我确实不是唯一的)。

如果我需要调整它,并在存储过程中,那么我只是调整它,并释放一个新的存储过程。我不必完全构建应用程序,因为代码已嵌入其中。

如果效果不好,我可以在查询之前处理它。

然而,linq上的每个演示文稿都说你不再需要学习SQL。然而,SQL是一种很好理解,成熟的语言。地狱,我宁愿我可以直接将SQL放入我的C#代码中,而不必学习新的语法。

甚至跨数据库访问的理论“如果我写在linq我可以使用任何数据库我想要的”对我来说没有兴趣,特别是如果我正在写SQL Azure,我确切地知道哪些数据库这将是。

这就是我的咆哮(这已经装瓶了一会儿!!)关于这个问题。我会去存储特效。如果你想要它类型安全,然后加载结果到定义良好的业务对象,或LINQ到SQL实体,如果你喜欢。

0

如何模块化?我发现LINQ-to-SQL的一件事是,如果出现错误,我们可能需要重新编译和重新部署整个应用程序(或者只是受影响的DLL),但是对于存储过程,我只需要修复一个存储过程和我的工作完成了。

在我看来,LINQ感觉更多adhoc和存储过程感觉更正式。

同样,我喜欢LINQ和随附的功能......但在LINQ-TO-SQL上并未完全销售。