2011-07-22 27 views
16

我在一些项目中使用了实体框架。在每个项目中,我都使用映射到实体的存储过程,这是因为存储过程的众所周知的好处 - 安全性,可维护性等。但是,99%的存储过程是基本的CRUD存储过程。这看起来像是否定了实体框架 - SQL生成的主要节省时间的功能之一。实体框架存储过程与生成的SQL

我读过一些有关存储过程与实体框架中生成的SQL的争论。虽然使用CRUD SPs对于安全性更好,而EF生成的SQL通常比必要的更复杂,但它是否真正购买了使用SP的性能或可维护性方面的任何内容?

这里是什么,我相信:

  • 大部分的时间,修改SP需要更新数据模型 反正。所以,在可维护性方面并没有太多的购买。
  • 对于Web应用程序,与数据库的连接使用特定于应用程序的单个用户ID。因此,用户甚至没有直接的数据库访问权限。这降低了安全效益。
  • 对于一个小型应用程序,使用生成的SQL稍微降低的性能可能不是什么大问题。对于音量高,性能关键的应用程序,EF甚至会明智地选择 ?另外,EF生成的插入/更新/删除语句 真的很糟糕吗?
  • 将每个属性发送到存储过程都有其自身的性能损失,而EF生成的代码只发送实际更改的属性。在对大型表进行更新时,增加的网络流量和更新所有属性的开销可能会否定存储过程的性能优势。

虽这么说,我的具体问题是:

上面列出的正确我的信念?现在ORM越来越受欢迎,总是使用SP的东西是“老派”的想法吗?根据你的经验,对于所有插入/更新/删除操作使用EF映射SP,或将EF生成的SQL用于CRUD操作并仅将SP用于更复杂的东西,哪种方法更好?

+0

'修改SP需要更新数据模型anyway' SP结束了显著提高应用程序的维护成本,不只是因为你不得不在至少5处(每一个变化每1 SP插入,更新,和删除,至少有一个用于选择,然后也用于实体模型),但也因为对于任何不是简单的CRUD操作的应用程序而言,您都将应用程序逻辑隐藏在应用程序之外,开发人员必须在不同的应用程序之间来回跳动IDE的。 –

回答

33

我认为总是使用SP的是有点老派。我曾经以这种方式进行编码,并且现在尽我所能在EF生成的代码中进行编码......当我遇到性能问题或其他特殊需求时,我会将其添加回战略SP中以解决特定问题....它不一定是或两者兼而有之。

我所有的基本CRUD操作都是直接生成EF代码 - 我的网络应用程序曾经有100多个或更多的SP,现在一般会有一打SP,其他所有事情都在我的C#代码中完成......并且我的生产力已经消除了95%的CRUD存储过程。

+0

+1一个好的,务实的方法 - 我可能也会这样。尽可能多地使用EF,但是如果知道**如果需要在某个地方的INSERT语句中调整性能的最后一滴性能,您可以使用存储过程来处理它。 –

+0

正如你所说因为性能问题,写一个SP真的很值得,但如何使用视图(当然不是SP中的select查询)呢?我找不到任何与这两种方法之间的比较有关的事情。 –

6

如果性能是您最关心的问题,那么您应该选择一个现有的使用EF的应用程序,禁用SP并对新版本进行基准测试。这是获得完全适用于您的情况的答案的唯一方法。您可能会发现,无论您做什么与自定义代码相比,您的性能需求都不够快,但在超大容量网站之外,我认为EF 4.1实际上是非常合理的。

从我的PoV来看,EF提高了开发人员的生产力。如果你正在为简单的CRUD操作编写SP,并且特别是插入/更新/删除,我真的没有看到你获得了很多性能,因为这些操作对于生成SQL来说非常简单。肯定有一些选择情况下,EF不会做最佳的事情,你可以通过编写一个SP来获得主要的性能提升(在Oracle中使用CONNECT BY进行分层查询的例子)。

处理这种类型的东西,最好的办法是写你的应用程序出租EF生成SQL。基准。找到存在性能问题的地方,并为这些地区编写SP。删除几乎不会是您需要执行此操作的情况之一。

正如你所说,这里的安全增益,多少削弱,因为你应该有反正都有自己的帐户为应用程序的应用程序层EF,所以你可以限制它做什么。 SP确实给了你更多的控制权,但在典型的使用情况下,我认为它不重要。

它不具有忠实地正确或错误的答案一个有趣的问题。我主要使用EF,因此我不必写通用的CRUD SP,而是可以将时间花在处理更复杂的案例上,所以对于我来说,我应该说你应该写出更少的案例。 :)

12

是你的信念是完全正确的。使用存储过程进行数据操作具有意义,主要如:

  • 数据库如下,其中变化的数据通过存储过程只允许
  • 您正在使用的视图或自定义查询映射你的实体严格的安全规则,你需要先进的逻辑在存储过程,以将数据传输回
  • 你有一些先进的逻辑程序(相关数据)任何其他原因

使用过程纯CUD其中提到的情况下,不适用是多余的,它不提供任何可测量的性能提升,除了单一的方案

  • 您将使用存储过程批量/批量修改

EF没有因此更改1000个记录导致1000个更新散装/批处理功能每个执行单独的数据库往返!但是这样的过程无论如何都不能映射到实体,并且必须通过函数导入(如果可能的话)或者直接以ExecuteStoreCommand或旧的ADO.NET(例如,如果您想使用表值参数)单独执行。

的完全不同的故事可以是R在CRUD其中存储过程可以得到显著的性能提升与自己优化的查询读取数据。

1

我E.J广泛认同,但也有一些其他的选择。这真的归结为特定系统的要求:

  • 您是否需要开发应用程序FAST? - 然后使用实体框架及其自动SQL
  • 需要细粒度和可靠的安全性? - 进入存储过程
  • 需要运行尽可能快吗? - 你可能正在看一些快乐的媒介!
0

在我看来,只要您的应用程序/数据库不会遇到性能问题,并且您主要使用CRUD数据库并使用一个数据库用户访问数据库,则最好使用生成的SQL。开发速度更快,更易维护,少数安全或更多隐私优势不值得(如果数据不那么敏感)。此外,使用基于模型的数据库访问或LINQ禁用了SQL注入的威胁。