我在几个项目中使用了实体框架。在每个项目中,我都使用映射到实体的存储过程,因为存储过程的众所周知的好处 - 安全性,可维护性等。但是,99%的存储过程是基本的CRUD存储过程。这似乎否定了实体框架的一个主要的,节省时间的功能 - SQL生成。
我已经阅读了有关存储过程与实体框架中生成的SQL的一些论点。虽然使用CRUD SP更好的安全性,并且EF生成的SQL通常比必要的更复杂,它是否真的在性能或可维护性方面购买任何东西来使用SP?
以下是我的看法:
话虽如此,我的具体问题是:
我的上述信仰是否正确? ORM现在越来越流行,是不是总是使用SP这个“旧学校”的想法?根据您的经验,哪种方式更适合使用EF - 为所有插入/更新/删除映射SP,或者使用EF生成的SQL进行CRUD操作,而只使用SP进行更复杂的操作?
答案 0 :(得分:34)
我认为使用SP的 总是 有些老派。我曾经以这种方式编写代码,现在我可以在EF生成的代码中尽我所能......当我遇到性能问题或其他特殊需求时,我会在战略SP中添加回来解决特定问题....它不一定是 - 或者两者都使用。
我所有的基本CRUD操作都是直接EF生成的代码 - 我的网络应用程序曾经拥有100个或更多的SP,现在一个典型的将拥有十几个SP,其他一切都是用我的C#代码完成的......我的通过消除那些95%的CRUD存储过程,生产力已经消失了。
答案 1 :(得分:12)
是的,你的信念绝对正确。使用存储过程进行数据操作主要有以下意义:
使用纯CUD的程序,其中未提及的案例适用是多余的,除了单一场景外,它不提供任何可测量的性能提升
EF没有批量/批处理功能,因此更改1000条记录会导致1000条更新,每条更新都使用单独的数据库往返执行!但是这样的过程无论如何都不能映射到实体,必须通过函数导入(如果可能)单独执行,或者直接作为ExecuteStoreCommand
或旧的ADO.NET执行(例如,如果你想使用表值参数)。
整个不同的故事可以是CR中的R,其中存储过程可以通过您自己的优化查询读取数据获得显着的性能提升。
答案 2 :(得分:6)
如果性能是您主要关心的问题,那么您应该使用现有的一个使用EF和SP的应用程序,禁用SP,并对新版本进行基准测试。这是获得完全适用于您的情况的唯一方法。您可能会发现,无论您做什么,与自定义代码相比,无法满足您的性能需求,但在非常高容量的网站之外,我认为EF 4.1实际上非常合理。
从我的PoV,EF是一个很好的开发人员生产力提升。如果您正在为简单的CRUD操作编写SP,并且特别是对于插入/更新/删除,我确实没有看到您在性能方面获得太多,因为这些操作对于生成SQL非常简单。肯定会有一些选择案例,其中EF不能做到最佳,你可以通过编写SP来获得主要的性能提升(例如,在Oracle中使用CONNECT BY的层次化查询)。
处理这类事情的最佳方法是编写应用程序,让EF生成SQL。基准吧。查找存在性能问题的区域并为其编写SP。删除几乎永远不会成为您需要执行此操作的案例之一。
正如您所提到的,此处的安全性收益有所减少,因为您应该在应用程序层上拥有EF,该应用程序层仍然拥有自己的应用程序帐户,因此您可以限制它的作用。 SP确实为您提供了更多控制权,但在典型用法中我认为不重要。
这是一个有趣的问题,没有真正正确或错误的答案。我主要使用EF,因此我不必编写通用的CRUD SP,而是可以把时间花在处理更复杂的情况上,所以对我来说,我会说你应该写的更少。 :)
答案 3 :(得分:1)
我与E.J广泛赞同,但还有其他几种选择。它实际上归结为特定系统的要求:
答案 4 :(得分:0)
在我看来,只要您的应用程序/数据库没有出现性能问题而且您主要使用数据库进行CRUD并仅使用一个数据库用户访问它,最好使用生成的SQL。它的开发速度更快,更易于维护,并且几乎没有安全性或更多的隐私权益(如果数据不那么敏感)。此外,使用基于模型的数据库访问或LINQ禁用了SQL注入的威胁。