【问题标题】:Call stored procedures with Entity Framework 6 code first approach in Asp.Net MVC 5在 Asp.Net MVC 5 中使用 Entity Framework 6 代码优先方法调用存储过程
【发布时间】:2016-12-27 08:47:40
【问题描述】:

我们正在使用 Ado.Net 从 ASP.NET MVC 中的 C# 代码处理数据库。我想使用实体框架,所以我需要使用存储过程,从 EF 调用存储过程。

很少有示例如何将存储过程与 Entity Framework 一起使用,但没有特定于 ASP.NET MVC 和代码优先的示例(至少我找不到任何示例)。

它们是一个好的开始,但我需要更多、更好的信息和更好的例子!

我有这个存储过程:

Create Procedure spAddEmployee  
    @Name nvarchar(50),  
    @Gender nvarchar(20),  
    @Salary int,  
    @EmployeeId int Out  
as  
Begin  
    Insert into tblEmployees 
    values(@Name, @Gender, @Salary)  

    Select @EmployeeId = SCOPE_IDENTITY()  
 End

所以@Name@Salary@Gender是输入参数,@EmployeeId是输出参数,它返回的是新添加员工的ID

谁能告诉我如何使用实体框架(代码优先)来调用这个带有参数的存储过程?

【问题讨论】:

    标签: c# asp.net-mvc stored-procedures ef-code-first entity-framework-6


    【解决方案1】:

    您可以在DbContext 类中调用存储过程,如下所示。

    this.Database.SqlQuery<YourEntityType>("storedProcedureName",params);
    

    更新:

    这是一个如何在 ActionResult 中调用你的 SP 的示例:

    public ActionResult ExecuteProcedure()
    {
       using(var  db = new CueEntities())
       {
         var parameter = 1;
         var query =  db.Database.SqlQuery<TestProcedure>("TestProcedure @parameter1", 
                        new  SqlParameter("@parameter1", parameter)).ToList();          
            return Json(query,JsonRequestBehavior.AllowGet);     
        }
    }
    

    第二次更新:

    对于多个参数,您可以轻松地像这样:

    var param1 = new SqlParameter(); 
    param1.ParameterName = "@Value1"; 
    param1.SqlDbType = SqlDbType.Int; 
    param1.SqlValue = val1;
    
    var param2 = new SqlParameter(); 
    param2.ParameterName = "@Value2"; 
    param2.SqlDbType = SqlDbType.NVarChar; 
    param2.SqlValue = val2;
    
    var result = db.tablename.SqlQuery("SP_Name @Value1,@Value2", param1, param2 ).ToList();
    

    【讨论】:

    • 好的。但是如何在控制器中以任何操作方法使用它?
    • 我需要在 Model 类中做一些特别的事情吗??
    • 但是有多个参数呢?我需要对它们中的每一个进行查询还是可以将它们写在一个查询命令中?
    • 好的。回到开头,上下文类中的代码,应该在 OnBuild 方法中还是在任何特定的地方?
    • 还有一件事要澄清!正如我从您的回答中了解到的那样,我可以在 Context 类中使用映射,也可以直接在 action 方法中不使用映射?
    【解决方案2】:

    第 1 步:

    创建您的存储过程脚本。

    IF OBJECT_ID ( 'usp_GetUserByCompany', 'P' ) IS NOT NULL   
        DROP PROCEDURE usp_GetUserByCompany; 
    
    GO
    CREATE PROCEDURE usp_GetUserByCompany
        @__ProfileId [uniqueidentifier],
        @__CompanyId [uniqueidentifier],
        @__Email VARCHAR (MAX),
    AS 
        SELECT *
        FROM [UserProfiles] AS [u]
        WHERE [u].[ProfileId] = @__ProfileId
            AND [u].[CompanyId] = @__CompanyId
            AND [u].[Email] = @__Email
    GO
    

    第 2 步

    为你的类创建模型

    public class UserProfile {
        public Guid Id { get;set; }
        public Guid CompanyId { get; set; }
        public Company Company { get;set; }
        public string Email { get;set; }
        ...
    }
    

    第 3 步

    转到您的 ApplicationDbContext 类

    public class ApplicationDbContext {
    
        ...
        
        public virtual DbQuery<UserProfile> UserProfiles { get; set; }
    }
    

    第 4 步

    为您的存储过程创建迁移

    dotnet ef migrations add Add_SP_GetUserProfileByCompany
    

    第 5 步

    在生成的迁移类中,在步骤 1

    上实现存储过程脚本
    public partial class Add_SP_GetUserProfileByCompany : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            var usp_GetUserByCompany = @"
                IF OBJECT_ID ( 'usp_GetUserByCompany', 'P' ) IS NOT NULL   
                    DROP PROCEDURE usp_GetUserByCompany; 
                
                GO
                CREATE PROCEDURE usp_GetUserByCompany
                    @__ProfileId [uniqueidentifier],
                    @__CompanyId [uniqueidentifier],
                    @__Email VARCHAR (MAX),
                AS 
                    SELECT *
                    FROM [UserProfiles] AS [u]
                    WHERE [u].[ProfileId] = @__ProfileId
                        AND [u].[CompanyId] = @__CompanyId
                        AND [u].[Email] = @__Email
                GO
            ";
    
            migrationBuilder.Sql(usp_GetUserByCompany);
        }
        ...
    }
    

    第 6 步

    在系统或服务等的某个地方的代码中,

    public List<UserProfile> GetUserProfileByCompanySP(Guid ProfileId, Guid CompanyId, string Email)
    {
        var dbContext = new ApplicationDbContext;
    
        var parameters = new object[]
        {
            new SqlParameter() {ParameterName = "@__ProfileId", Direction = ParameterDirection.Input, SqlDbType = SqlDbType.UniqueIdentifier, Value = ProfileId},
            new SqlParameter() {ParameterName = "@__CompanyId", Direction = ParameterDirection.Input, SqlDbType = SqlDbType.UniqueIdentifier, Value = CompanyId},
            new SqlParameter() {ParameterName = "@__Email", Direction = ParameterDirection.Input, SqlDbType = SqlDbType.VarChar, Size = 64, Value = Email},
        };
    
        var output = dbContext.UserProfiles.FromSql("usp_GetUserByCompany @__ProfileId, @__CompanyId, @__Email", parameters).ToList();
        ...
    }
    

    【讨论】:

      【解决方案3】:

      您应该使用CodeFirstStoredProcs 库。它最适合代码优先方法,它支持存储过程的所有功能。我在很多项目中都使用它。

      您也可以使用 Code first 用户函数库来调用用户定义的函数。我已经为它创建了库。 CodeFirstFunctions

      【讨论】:

      • 有趣,新的东西。能否请您举例说明如何根据我的问题、我拥有的存储过程以及与之相关的所有内容。谢谢
      • 当然。您可以访问项目站点 URL codeproject.com/articles/179481/code-first-stored-procedures 了解详细信息。如果您有任何疑问,请提供您的代码,我会通知您。
      • 我现在只有那个存储过程。它被缩短了,但如果回答得当,它涵盖了我的所有需求
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多