ASP.NET MVC:调用存储过程的最佳方法

时间:2010-11-23 19:30:51

标签: asp.net-mvc linq-to-sql stored-procedures

我正在尝试确定调用存储过程的最佳方法。

我是ASP.NET MVC的新手,我已经阅读了很多关于Linq to SQL和Entity Framework以及Repository Pattern的内容。说实话,我很难理解L2S和EF之间的真正差异......但我想确保我在我的应用程序中构建的内容是正确的。

目前,我需要正确调用存储过程:a)保存一些用户信息并获得响应,b)获取产品目录的一些信息。

到目前为止,我已经创建了一个Linq to SQL .dbml文件,从Server Explorer中选择了sotred过程并将该实例拖到.dbml中。我现在正在调用存储过程:

MyLinqModel _db = new MyLinqModel();
_db.MyStoredProcedure(args);

我知道必须更多参与......而且我在我的控制器中这样做,我明白这不是一个好习惯。

有人能认出我的问题在这里吗?

5 个答案:

答案 0 :(得分:19)

如果你要做的就是调用存储过程,那么LINQ和EF可能有点过分。

我使用Enterprise Library,但ADO.NET也可以正常工作。

请参阅this tutorial

简要地说(从参考文章中无耻地复制和粘贴):

    SqlConnection conn = null;
    SqlDataReader rdr  = null;

    // typically obtained from user
    // input, but we take a short cut
    string custId = "FURIB";

    Console.WriteLine("\nCustomer Order History:\n");

        // create and open a connection object
        conn = new SqlConnection("Server=(local);DataBase=Northwind; Integrated Security=SSPI");
        conn.Open();

        // 1.  create a command object identifying
        //     the stored procedure
        SqlCommand cmd  = new SqlCommand(
            "CustOrderHist", conn);

        // 2. set the command object so it knows
        //    to execute a stored procedure
        cmd.CommandType = CommandType.StoredProcedure;

        // 3. add parameter to command, which
        //    will be passed to the stored procedure
        cmd.Parameters.Add(
            new SqlParameter("@CustomerID", custId));

        // execute the command
        rdr = cmd.ExecuteReader();

        // iterate through results, printing each to console
        while (rdr.Read())
        {
            Console.WriteLine(
                "Product: {0,-35} Total: {1,2}",
                rdr["ProductName"],
                rdr["Total"]);
        }
    }

<强>更新

我错过了你说你在控制器中这样做的部分。

不,这不是正确的方法。

您的控制器实际上只应参与编排视图构造。创建一个单独的类库,称为“数据访问层”或不太通用的东西,并创建一个类来处理调用存储过程,从结果中创建对象等。关于如何处理它有很多意见,但也许是最常见的是:

View
|
Controller
|
Business Logic
|
Data Access Layer
   |--- SQL (Stored procs)
           -Tables
           -Views
           -etc.
   |--- Alternate data sources
           -Web services
           -Text/XML files
           -blah blah blah.

MSDN has a decent tutorial on the topic.

答案 1 :(得分:3)

试试这个:

读:

var authors = context.Database.SqlQuery<Author>("usp_GetAuthorByName @AuthorName", 
new SqlParameter("@AuthorName", "author"));

更新

var affectedRows = context.Database.ExecuteSqlCommand
("usp_CreateAuthor @AuthorName = {0}, @Email= {1}", 
"author", "email");

从此链接:http://www.dotnetthoughts.net/how-to-execute-a-stored-procedure-with-entity-framework-code-first/

我会选择David Lively提到的框架,而不是控制器中的例程。只需将结果作为IEnumerable<blah>从一个单独的存储库类中的函数传回给编辑,如果更新成功进行更新,则返回一个布尔值。

答案 2 :(得分:2)

LINQ to SQL和ADO.NET EF将读取的存储过程附加到您用来对其各种实体进行的数据/对象上下文类。对于创建,更新和删除,您可以创建一个proc来映射模型生成的实体的属性,并使用实体映射窗口(现在忘记确切的名称),您可以使用proc参数映射实体字段。因此,假设您有一个Customers表,EF会生成一个客户实体,并且您可以在尝试更新/插入/删除时将proc参数映射到Customer实体的属性。

现在,你可以将CUD proc映射到一个函数,但我不知道所有的反响;我喜欢我刚才提到的最好的方式。

HTH。

答案 3 :(得分:-1)

我常见的模式是通过依赖注入将存储库接口传递到控制器。您使用的持久性/ orm技术的选择确实是另一个问题,与您使用MVC无关。使用存储库模式和编码到抽象(接口)可以通过模拟存储库来轻松测试应用程序。

我认为你也应该尝试使用尽可能少的存储过程。这意味着您可以更轻松地单独测试逻辑(单元测试),而无需连接到数据库。我强烈推荐看看NHibernate。学习曲线相当陡峭,但您可以完全控制映射和配置。显然,出于性能原因,您需要存储过程,但主要使用ORM非常有用。

答案 4 :(得分:-5)

我无法想象您的目标是能够调用存储过程。对我来说,听起来好像你需要忘记存储过程并使用Linq to Sql。我说L2S因为EF要学习更多,在这种情况下不需要。