实体框架和存储过程

Dis*_*ile 4 c# vb.net stored-procedures entity-framework linq-to-sql

我注意到在Entity Framework设计器中,您可以映射Insert,Update和Delete操作的存储过程.有没有办法为Select操作执行此操作,或者是否有新的数据库访问代码方向,我们不再为基本的选择操作编写存储过程了?

我工作的公司非常坚持总是使用存储过程进行每个数据库操作,即使实体框架通过调用sp_executesql使调用安全.

LINQ to SQL和Entity Framework似乎已经不再使用存储过程来选择数据了.这是一个准确的陈述吗?

只是为了澄清我的问题:

我的数据库中有一个名为Product的表.我使用实体框架中的向导来生成我的模型......所以我现在有一个名为Product的实体.当我执行以下查询时:

db.Products.SingleOrDefault(p => p.Id == 1);
Run Code Online (Sandbox Code Playgroud)

它生成的代码类似于:

EXEC sp_executesql N'SELECT * FROM Product'
Run Code Online (Sandbox Code Playgroud)

当我真的想要做的事情:

EXEC up_GetProduct @Id = 1
Run Code Online (Sandbox Code Playgroud)

如果使用SingleOrDefault无法做到这一点,我就可以了.我更愿意拥有以下内容:

db.Products.GetProduct(1);
Run Code Online (Sandbox Code Playgroud)

这是通常完成的事情还是大多数人只是让它动态生成SQL?

Nel*_*mel 7

实体本身不允许存储过程进行选择.有几个原因.脱离我的头顶:

  1. 如何在存储过程中添加where子句?您可能必须使用LINQ to Objects执行此操作并且查询效率低下,或者以某种方式能够将自定义映射添加到存储过程属性.虽然并非不可能,但它肯定会引入一些实现复杂性
  2. 实体可以具有用于在查询中进行连接的关系.使用存储过程,您又会遇到类似的问题.如果你有OrderOrderItem桌子,你怎么加入?您可以运行SelectOrder并为您运行的每个订单运行SelectOrderItem(1 + n个查询),或者让一个存储过程同时返回两个,或者作为一个带有重复Order数据的结果集,或者两个结果集.然后,您必须指定映射到实体的方式.如果必须手动指定映射,则会破坏您必须设置的实体关系的目的.
  3. 你怎么做分页?使用LINQ to Entities,您可以公开IQueryable业务层或UI层(由您决定).然后进行LINQ过滤,修改SQL并使其高效.使用存储过程,您将再次以某种方式手动定义所有这些,或使用LINQ to对象进行过滤.
  4. LINQ允许你select new { o.Column1, o.Column2 }.这会生成SQL,只选择您需要的那两列.如果你有一个BLOB/ 非常有用VARCHAR(MAX).使用存储过程,您通常会返回每一列(在很多方面都会浪费).您可以拆分成(GetOrderDetailMainGetOrderDetailImages/或类似的)存储过程,但创建每个组合是不可行的.

在我看来,如果你将使用EF框架,让它为你做CRUD.使用存储过程来处理复杂的逻辑,例如全文搜索,特定查询太慢等等.否则你将无法从中受益.

编辑:当然存储过程有好处.它们是预先编译/预编译的,定义良好的"数据库API",你不需要提供对表的访问(虽然使用SP CRUD,你实际上可以做同样的事情),更容易调试/调优查询,更容易知道哪些查询可以调整,可以进行批处理等.但是,对于简单的CRUD,您必须问自己,实现/管理存储过程的开销是否值得.