仅通过存储过程查询数据库是一种好方法吗?

时间:2013-11-25 16:53:33

标签: c# sql-server entity-framework stored-procedures linq-to-sql

当我开发ASP.NET网站时,我确实喜欢将Entity Framework与数据库优先或代码优先模型(+ asp.net mvc控制器脚手架)一起使用。

对于需要访问现有数据库的应用程序,我自然会想到创建一个数据库模型并使用asp.net mvc脚手架在几分钟内完成所有基本的CRUD操作,几乎没有开发成本。

但我与一位朋友讨论过,他告诉我只能通过存储过程访问存储在数据库中的数据是最好的方法

我的问题是,您如何看待这句话?为数据库中的表上的任何所需操作创建存储过程是否更好(例如,在此表上创建和读取,仅在另一个表上更新和删除,...)?这样做的优点/缺点是什么,而不是使用从数据库中的表创建的数据库优先模型?

我首先想到的是,通过存储过程完成所有事情会使开发成本翻倍,因为您必须编写这些存储过程,而Entity Framework可以在几次单击中提供DbContext,允许我使用LINQ over Entities,...但后来我读了一些关于Ownership Chains的东西,这些东西可以通过设置执行存储过程的权限而没有对表上的任何操作(选择,插入,更新,删除)的权限来提高安全性。< / p>

感谢您的回答。

6 个答案:

答案 0 :(得分:2)

它的成本效益分析。作为一个专注于数据库的人,我同意这个说法。这是最好的。它还使您的代码更易于阅读(没有疯狂的sql语句使其更加清晰)。通过缓存的执行计划提高性能。易于修改查询而无需重新编译代码,eetc。

与我合作的许多人都并不熟悉编写SPROC,所以它往往与他们一起使用它们。我个人认为没有理由在你的代码中埋葬SQLStatments。他们倾向于回避他们,而这对他们来说是更多的工作。

答案 1 :(得分:1)

这主要是基于意见的问题,答案可能取决于具体情况。使用存储过程定义是查询数据库的最佳方法之一,但自从Entity Framework出现以来,它被广泛使用。实体框架的优点是它提供了更高级别的抽象。

  

实体框架应用程序提供以下好处:

     
      
  • 应用程序可以在更加以应用程序为中心的概念模型方面工作,包括具有继承的类型,复杂的成员,
      和关系。
  •   
  • 应用程序可以从特定数据引擎或存储架构的硬编码依赖项中解脱出来。
  •   
  • 概念模型和特定于存储的架构之间的映射可以在不更改应用程序代码的情况下进行更改。
  •   
  • 开发人员可以使用一致的应用程序对象模型,该模型可以映射到各种存储模式,可能在实现中实现   不同的数据库管理系统。
  •   
  • 可以将多个概念模型映射到单个存储架构。
  •   
  • 语言集成查询(LINQ)支持为针对概念模型的查询提供编译时语法验证。
  •   

您还可以查看此相关问题Best practice to query data from MS SQL Server in C Sharp?

答案 2 :(得分:1)

以下是一些存储过程的优点

  • 使用存储过程
  • 将多个语句封装为单个事务
  • 使用临时表实现业务逻辑
  • 通过使用表来捕获/记录错误来更好地处理错误
  • 参数验证/域验证可以在数据库级别完成
  • 强制选择索引来控制查询计划
  • 使用sp_getapplock随时强制执行单个程序

此外,实体框架将为您所做的每个请求增加开销,因为实体框架将为每个查询使用反射。因此,通过实现存储过程,您将在编译时获得时间,而不是每次都像正常的实体框架查询一样进行解释。

下面的链接给出了为什么要使用实体框架

的一些原因

http://kamelbrahim.blogspot.com/2013/10/why-you-should-use-entity-framework.html

希望这可以启发你一点

答案 3 :(得分:1)

是的,这是一个很好的方法。

是否是最佳方法,这取决于很多因素,其中一些因素你还不知道。

一个重要的因素是将会有多少进一步的发展,以及多少维护。如果初始开发是整个工作的一个重要部分,那么您应该使用一种尽可能快速简便的方法。

如果您将长时间使用和维护系统,则应该更少关注初始开发时间,更多关注在系统启动和运行后对系统进行更改的难易程度。使用存储过程是根据确切的数据布局减少代码的一种方法,并允许您在没有大量停机时间的情况下进行更改。

请注意,它不一定是存储过程和实体框架之间的选择。您还可以将存储过程与Entity Framework一起使用。

答案 4 :(得分:0)

所以我会给你一个建议,这将是我做过的事情,但没有多少人会说“我这样做”。

所以,是的,我在使用ADO.NET时使用了存储过程。

我也(有时)使用ORM,比如NHibernate和EntityFramework。

当我使用ADO.NET时,我使用存储过程。

当您从数据库获取数据时,您必须将其转换为DotNet端的内容。

最快的方法是将数据放入DataTable或DataSet。

我不再喜欢这种方法。虽然它可以用于RAPID开发(“只是将数据填入数据表中”)......但它对维护来说效果不佳,即使维护时间只有2-3个月。

那么我将数据放入什么?

我创建DTO / POCO对象并将数据库中的数据水合成这些对象。

例如。

NorthWind数据库有

Customer(s)
Order(s)
and OrderDetail(s)

所以我创建了一个名为Order.cs,Order.cs和OrderDetail.cs的csharp类。 这些仅包含实体的属性。大多数情况下,属性简单地反映了该实体的数据库中的列。 (Order.cs具有属性,模拟Select * from dbo.Order,例如OrderID = 123)。

然后我创建一个子集合对象

public class OrderCollection : List<Order>{}

然后父对象获取属性。

public class Customer ()
{
/* a bunch of scalar properties */
public OrderCollection Orders {get;set;}
}

所以现在你有一个存储过程。它获取数据。

当数据返回时,获取它的一种方法是使用IDataReader。 (.ExecuteReader)。

当这个IDataReader返回时,我循环遍历它,并填充Customer(.cs),Orders和OrderDetails。

这是基本的,穷人的ORM(对象关系映射)。

回到我如何对存储过程进行编码,我将编写一个返回3个结果集的过程(一次db命中)并返回有关Customer,Order(s)(如果有)和OrderDetails的信息。 (如果存在的话)。

请注意,我没有做很多JOINING 当你在c.CustomerID = o.CustomerId上执行“选择*来自dbo.Customer c join dbo.Orders o时,你会注意到你在第一列中得到了冗余数据。这是我不喜欢的。

我更喜欢多个结果集OVER加入并带回冗余数据的单个结果集。

现在进行一些特别的小动作。

每当我从表中选择时,我总是选择该表上的所有列。

因此,每当我编写需要客户数据的存储过程时,我都会这样做 从dbo.Customer中选择A,B,C,D,E,F,G,其中(......)

现在,很多人都会争辩。 “为什么你带回的信息比你需要的多?”

嗯,无论如何,真正的ORM会这样做。所以我是穷人,反映了这一点。 并且,我的代码用于从存储过程中获取结果集以将其转换为对象的实例........保持一致。

因为如果您编写3个存储过程,并且每个存储过程都从Customer表中选择数据,但是您选择不同的列和/或以不同的顺序,您的“对象映射器”代码需要为每个存储过程提供一个方法。 / p>

这种ADO.NET方法对我很有帮助。 而且,一旦我的团队将ADO.NET替换为真正的ORM,并且由于我们从一开始就使用ADO.NET的方式,这种转换非常无痛。

快速经验法则:

1.  If using ADO.NET, use stored procedures.
2.  Get multiple result-sets, instead of redundant data via joins.
3.  Make your columns consistent from any table you select from.
4.  Take the results of your stored procedure call, and write a "hydrater" to take that info and put into your domain-model as soon as you can.  (the .cs classes)
多年来,这对我有好处。

祝你好运。

答案 5 :(得分:-2)

在我看来:

  1. 存储过程用大铁数据库“语言”编写,如PL / SQL或T-SQL
  2. 存储过程通常无法在您编写UI的同一IDE中进行调试。
  3. 当出现问题时,存储过程不会提供太多反馈。
  4. 存储过程无法传递对象。
  5. 存储过程隐藏业务逻辑。
  6. 资料来源: http://www.codinghorror.com/blog/2004/10/who-needs-stored-procedures-anyways.html