实体框架存储过程与生成的SQL

DCN*_*YAM 19 entity-framework entity-framework-4

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

我已经从实体框架中读到了一些关于存储过程与生成的SQL的争论.虽然使用CRUD SP更好的安全性,并且EF生成的SQL通常比必要的更复杂,它是否真的在性能或可维护性方面购买任何东西来使用SP?

以下是我的看法:

  • 大多数情况下,修改SP无论如何都需要更新数据模型.因此,在可维护性方面并没有太大的收获.
  • 对于Web应用程序,与数据库的连接使用特定于应用程序的单个用户标识.因此,用户甚至没有直接的数据库访问权限.这降低了安全性.
  • 对于小型应用程序,使用生成的SQL的性能略有下降可能不是什么大问题.对于大批量,性能关键的应用,EF甚至是明智的选择吗?另外,EF生成的插入/更新/删除语句真的那么糟糕吗?
  • 将每个属性发送到存储过程都有自己的性能损失,而EF生成的代码只发送实际更改的属性.在对大型表进行更新时,增加的网络流量和更新所有属性的开销可能会抵消存储过程的性能优势.

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

上面列出的我的信念是否正确?ORM现在越来越流行,是不是总是使用SP这个"旧学校"的想法?根据您的经验,哪种方式更适合使用EF - 为所有插入/更新/删除映射SP,或者使用EF生成的SQL进行CRUD操作,而只使用SP进行更复杂的操作?

E.J*_*nan 35

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

我所有的基本CRUD操作都是直接的EF生成代码 - 我的网络应用程序曾经拥有100个或更多的SP,现在典型的一个将有十几个SP,其他一切都是用我的C#代码完成的......我的工作效率已经不见了通过消除那些95%的CRUD存储过程来解决问题.


Lad*_*nka 12

是的,你的信念绝对正确.使用存储过程进行数据操作主要有以下意义:

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

使用纯CUD的程序(其中未提及的案例适用)是多余的,除了单一场景之外,它不提供任何可测量的性能提升

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

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

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


Tri*_*dus 6

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

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

处理这类事情的最好方法是编写你的应用程序,让EF生成SQL.基准吧.查找存在性能问题的区域并为其编写SP.删除几乎永远不会成为您需要执行此操作的案例之一.

正如您所提到的,这里的安全性增益有所减少,因为您应该在应用程序层上拥有EF,该应用程序层仍然拥有自己的应用程序帐户,因此您可以限制其功能.SP确实为您提供了更多控制权,但在典型用法中我并不认为这很重要.

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