【问题标题】:Entity Framework Stored Procedures vs Generated SQL实体框架存储过程与生成的 SQL
【发布时间】:2011-10-11 01:55:10
【问题描述】:

我在几个项目中使用了实体框架。在每个项目中,我都使用映射到实体的存储过程,因为存储过程众所周知的好处——安全性、可维护性等。但是,99% 的存储过程是基本的 CRUD 存储过程。这似乎否定了 Entity Framework 的主要省时特性之一——SQL 生成。

我已经阅读了一些关于存储过程与实体框架中生成的 SQL 的争论。虽然使用 CRUD SP 的安全性更好,而且 EF 生成的 SQL 往往比必要的复杂,但使用 SP 真的在性能或可维护性方面有什么好处吗?

这是我的信念:

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

话虽如此,我的具体问题是:

我上面列出的信念是否正确?现在 ORM 越来越受欢迎,总是使用 SP 的想法是“老派”吗?根据您的经验,哪个是使用 EF 的更好方法 - 为所有插入/更新/删除映射 SP,还是使用 EF 生成的 SQL 进行 CRUD 操作,只使用 SP 处理更复杂的事情?

【问题讨论】:

  • modifying an SP requires updating the data model anyway SP 最终会显着增加应用程序的维护成本,这不仅仅是因为您必须在至少 5 个位置进行每次更改(插入、更新和删除各 1 个 SP,在至少一个用于选择,然后在您的实体模型中),而且因为对于任何不是简单 CRUD 操作的事情,您都将应用程序逻辑隐藏在应用程序之外,并且开发人员必须在不同的 IDE 之间来回切换。

标签: entity-framework entity-framework-4


【解决方案1】:

我认为总是使用 SP 有点老套。我以前是这样编码的,现在在 EF 生成的代码中尽我所能……当我遇到性能问题或其他特殊需求时,我会重新添加战略 SP 来解决特定问题……它不必是其中一个或 - 两者都使用。

我所有的基本 CRUD 操作都是直接 EF 生成的代码 - 我的 Web 应用程序过去有 100 个或更多的 SP,现在一个典型的应用程序将有十几个 SP,其他所有操作都在我的 C# 代码中完成......通过消除 95% 的 CRUD 存储过程,生产力大大提高。

【讨论】:

  • +1 一个好的、务实的方法——我可能也会这样做。尽可能多地使用 EF,但要知道 if 您需要在某处的 INSERT 语句中调整最后的性能下降,您可以 - 通过使用存储的 proc 来实现。
  • 正如您所说,由于性能问题,编写一个 SP 确实值得,但是使用视图(当然而不是 SP 中的选择查询)怎么样?我找不到与这两种方法之间的比较相关的任何内容。
【解决方案2】:

是的,你的信念是绝对正确的。使用存储过程进行数据操作的意义主要在于:

  • 数据库遵循严格的安全规则,只允许通过存储过程更改数据
  • 您正在使用视图或自定义查询来映射您的实体,并且您需要存储过程中的高级逻辑来推回数据
  • 出于任何其他原因,您在过程中有一些高级逻辑(与数据相关)

在未提及的情况下使用纯 CUD 的程序是多余的,除了单一场景外,它不会提供任何可衡量的性能提升

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

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

整个不同的故事可以是 CRUD 中的 R,其中存储过程可以通过您自己的优化查询读取数据获得显着的性能提升。

【讨论】:

    【解决方案3】:

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

    从我的 PoV 来看,EF 极大地提高了开发人员的工作效率。如果您正在为简单的 CRUD 操作编写 SP,尤其是对于插入/更新/删除,我真的看不到您在性能上获得太多提升,因为这些操作生成 SQL 非常简单。在某些 Select 情况下,EF 不会做最佳的事情,您可以通过编写 SP 来获得显着的性能提升(以 Oracle 中使用 CONNECT BY 的分层查询为例)。

    处理这类事情的最佳方法是编写让 EF 生成 SQL 的应用程序。对其进行基准测试。查找存在性能问题的区域并为这些区域编写 SP。删除几乎永远不会成为您需要执行此操作的情况之一。

    正如您所提到的,这里的安全增益有所降低,因为您应该在应用程序层上拥有 EF,无论如何该应用程序都有自己的帐户,因此您可以限制它的作用。 SP 确实为您提供了更多控制权,但在典型用法中我认为这并不重要。

    这是一个有趣的问题,没有真正正确或错误的答案。我主要使用 EF,这样我就不必编写通用的 CRUD SP,而是可以将时间花在处理更复杂的案例上,所以对我来说,我会说你应该少写一些。 :)

    【讨论】:

      【解决方案4】:

      我大致同意 E.J,但还有其他几种选择。这真的归结为特定系统的要求:

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

      【讨论】:

        【解决方案5】:

        在我看来,只要您的应用程序/数据库没有遇到性能问题,并且您主要将数据库用于 CRUD 并仅使用一个 DB 用户访问它,那么最好使用生成的 SQL。它的开发速度更快,可维护性更高,并且为数不多的安​​全性或更多的隐私优势是不值得的(如果数据不那么敏感)。此外,使用基于模型的数据库访问或 LINQ 可以消除 SQL 注入的威胁。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-19
          • 1970-01-01
          • 2016-12-02
          相关资源
          最近更新 更多