【问题标题】:Entity Framework Core - Using Stored Procedure with output parametersEntity Framework Core - 使用带有输出参数的存储过程
【发布时间】:2017-12-28 09:48:19
【问题描述】:

我正在尝试将存储过程与新的 Entity Framework Core 一起使用。我需要尽快开始新项目,它将是 ASP.Net 5,但不确定 Entity Framework 是否适合这项工作。该应用程序将每分钟触发几个存储过程,我需要输出参数。 EF 会对此有好处还是我应该使用 ADO.Net?

我已经尝试过 FromSql 和 database.ExecuteSqlCommand 但没有成功。

using (AppDbContext db = factory.Create())
        {
            var in1 = new SqlParameter
            {
                ParameterName = "ParamIn1",
                DbType = System.Data.DbType.Int64,
                Direction = System.Data.ParameterDirection.Input
            };
            var in2 = new SqlParameter
            {
                ParameterName = "ParamIn2",
                DbType = System.Data.DbType.String,
                Direction = System.Data.ParameterDirection.Input
            };
            var out1 = new SqlParameter
            {
                ParameterName = "ParamOut1",
                DbType = System.Data.DbType.Int64,
                Direction = System.Data.ParameterDirection.Output
            };
            var out2 = new SqlParameter
            {
                ParameterName = "ParamOut2",
                DbType = System.Data.DbType.String,
                Direction = System.Data.ParameterDirection.Output
            };

            var result = db.Database.ExecuteSqlCommand("exec spTestSp", in1, in2, out1, out2);
        }

【问题讨论】:

    标签: asp.net entity-framework entity-framework-core


    【解决方案1】:

    应该可以,但我相信您还需要在命令语句中包含参数名称和OUT 关键字

    var sql = "exec spTestSp @ParamIn1, @ParamIn2, @ParamOut1 OUT, @ParamOut2 OUT";
    var result = db.Database.ExecuteSqlCommand(sql, in1, in2, out1, out2);
    
    var out1Value = (long) out1.Value;
    var out2Value = (string) out2.Value;
    

    【讨论】:

    • 确认这个作品。如何做到这一点有几种不同的浮动方式不起作用。
    • 每次粘贴时请务必设置 OUT PARAMETER 的长度 SqlParameter job1 = cmd2.Parameters.Add("@job", SqlDbType.VarChar, 50);
    • @Muflix 当我没有指定长度时它给我一个错误
    • 能否提供完整的参数声明示例?
    【解决方案2】:

    StoredProcedureEFCore 扩展支持输出参数

    那么用法是这样的

    List<Model> rows = null;
    
    ctx.LoadStoredProc("dbo.ListAll")
       .AddParam("limit", 300L)
       .AddParam("limitOut", out IOutParam<long> limitOut)
       .Exec(r => rows = r.ToList<Model>());
    
    long limitOutValue = limitOut.Value;
    
    ctx.LoadStoredProc("dbo.ReturnBoolean")
       .AddParam("boolean_to_return", true)
       .ReturnValue(out IOutParam<bool> retParam)
       .ExecNonQuery();
    
    bool b = retParam.Value;
    
    ctx.LoadStoredProc("dbo.ListAll")
       .AddParam("limit", 1L)
       .ExecScalar(out long l);
    

    【讨论】:

      【解决方案3】:

      上面由@Nkosi 和部分由@Whistler 描述的解决方案的完整示例,以方便未来的读者!

      在我的示例中,我试图执行数据库中存在的存储过程以获取特定路径。

      string tableName = "DocumentStore";
      string path;
      
              var in1 = new SqlParameter
              {
                  ParameterName = "TableName",
                  Value = tableName,
                  Size = Int32.MaxValue,
                  DbType = System.Data.DbType.String,
                  Direction = System.Data.ParameterDirection.Input
              };
      
              var out1 = new SqlParameter
              {
                  ParameterName = "Path",
                  DbType = System.Data.DbType.String,
                  Size = Int32.MaxValue,
                  Direction = System.Data.ParameterDirection.Output
              };
      
              //_context is DbContext Object
              _context.Database.ExecuteSqlCommand("EXEC GetFileTableRootPath @TableName, @Path OUT", in1,out1);
      
              path = out1.Value.ToString();
      

      【讨论】:

      • 如果有人来这里,Size 表示数据类型的字节大小(例如 int32 为 4 或 int64 为 8)或 sql 表中描述的字符串大小,如 varchar(32)大小=32
      【解决方案4】:
      **This is a working example**
      
      1)  Create sample SP
      
      --exec [dbo].sampleCalc 100,0,''
      CREATE PROCEDURE[dbo].sampleCalc
         @inputPara int,
         @outputPara1 INT OUTPUT,
         @outputPara2 varchar(50) OUTPUT
      AS
      BEGIN
          set @outputPara1 = @inputPara + 100
          set @outputPara2 = 'result is ' + convert(varchar(50), @outputPara1)
          print @outputPara1
          print @outputPara2
      END
      
      2) C#
      
      var param = new SqlParameter[] {
      new SqlParameter() {
       ParameterName = "@inputPara",
       SqlDbType =  System.Data.SqlDbType.Int,
       Direction = System.Data.ParameterDirection.Input,
       Value = 100
      },
      new SqlParameter() {
       ParameterName = "@outputPara1",
       SqlDbType =  System.Data.SqlDbType.Int,
       Direction = System.Data.ParameterDirection.Output,
      },
      new SqlParameter() {
       ParameterName = "@outputPara2",
       SqlDbType =  System.Data.SqlDbType.VarChar,
       Direction = System.Data.ParameterDirection.Output,
       Size = 50
      }};
      
      
      var sql = "exec sampleCalc @inputPara, @outputPara1 OUT, @outputPara2 OUT";
      var resultObj = _context.Database.ExecuteSqlRaw(sql, param.ToArray());
      
      var out1Value = param[1].Value.ToString();
      var out2Value = param[2].Value.ToString();    
      

      【讨论】:

      • 请解释为什么以及如何补充所有现有答案。如果新答案没有显示任何本质上的新内容,则无需发布新答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多