Entity Framework Core - 使用带有输出参数的存储过程

14

我想在新的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);
        }
4个回答

23

这应该能够运行,但我认为你还需要在命令语句中包含参数名称和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;

确认这个可行。有几种不起作用的浮动方法在各处流传。 - user3230660
每次粘贴时,请确保为OUT参数设置长度 SqlParameter job1 = cmd2.Parameters.Add("@job", SqlDbType.VarChar, 50); - JB's
1
@Muflix,在我没有指定Length时,它给我报错了。 - JB's
请您提供带有参数声明的完整示例,好吗? - Muflix

5
**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();    

1
请解释为什么以及如何补充所有现有答案。如果它们没有显示任何本质上新的东西,那么不需要发布新答案。 - Gert Arnold
@GertArnold 我相信 DEEPMOC 是想展示如何使用 Entity Framework 的 ExecuteSqlRaw 方法来完成这个操作。这对我的问题很有帮助! - RoastBeast
我也是,如果我没记错的话,因为Blazor和IDbContextFactory的建议,我不得不使用ExecuteSqlRaw。 - jpp1jpp1

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();

1
如果有人来这里,Size 是指数据类型的字节大小(例如 int32 的字节数为 4,int64 的字节数为 8),或者在 SQL 表中描述的字符串大小,如 varchar(32),其中 size=32。 - ibram

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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接