繁体   English   中英

如何从存储过程 EF Core 3.1 中获取多个 OUTPUT 参数

[英]How to get Multiple OUTPUT parameters from stored procedure EF Core 3.1

我一直在尝试修改这里接受的答案该答案似乎利用了RelationalDataReader ,以便从产品所有者希望尽可能多的数据库驱动的 API 中获取某些计算日期的 2 个 OUTPUT 参数。

我有一个存储过程,它根据我存储在表中的 SQL 查询计算开始和结束日期,以便他们添加另一个日期范围所要做的就是将它添加到表中,其余的将在 UI 上就位和管道的其余部分。

RDFacadeExtensions 类的第一部分是相同的,但我认为我可以简单地添加更多参数并将它们取回,但我似乎遗漏了一些东西。

var ID = new SqlParameter("ID", 5)
{
    Direction = ParameterDirection.Input,
    DbType = DbType.Int32,
    Size = 500
};

var _beginDate = new SqlParameter("BeginDate", "")
{
    Direction = ParameterDirection.Output,
    DbType = DbType.String,
    Size = 500
};

var _endDate = new SqlParameter("EndDate", "")
{
    Direction = ParameterDirection.Output,
    DbType = DbType.String,
    Size = 500
};

这一切似乎很正常,然后我执行以下操作:

string begin;
string end;
var sql = $"exec [dbo].[GetDateRange] @ID, @BeginDate OUTPUT, @EndDate OUTPUT";

using (var dr = context.Database.ExecuteSqlQuery(sql, ID, _beginDate, _endDate))
{
    while (dr.DbDataReader.Read())
    {
        var thing = dr.DbDataReader[0].ToString();
    }
    dr.DbDataReader.Close();
    begin = _beginDate.Value.ToString();
    end = _endDate.Value.ToString();
}

在使用结束之前,我短暂地获得了第一次约会,但我似乎永远无法获得第二次约会。 一旦数据读取器关闭,我也有空字符串。

如果重要的话,我的存储过程就是这样:

    @ID INT,
    @BeginDate DATE OUTPUT,
    @EndDate DATE OUTPUT
BEGIN
    SET NOCOUNT ON;
    DECLARE @Query1 NVARCHAR(1000)
    DECLARE @Query2 NVARCHAR(1000)

    SELECT @Query1 = BeginDate,
           @Query2 = EndDate 
    FROM DateRange 
    WHERE ID = @ID
    
    DECLARE @ParmDefinition1 NVARCHAR(50) = N'@BeginDateOUT DATE OUTPUT';
    DECLARE @ParmDefinition2 NVARCHAR(50) = N'@EndDateOUT DATE OUTPUT';

    EXEC sp_executesql @Query1, @ParmDefinition1, @BeginDateOUT = @BeginDate OUTPUT
    EXEC sp_executesql @Query2, @ParmDefinition2, @EndDateOUT = @EndDate OUTPUT
END

或者也许我的存储过程是问题所在。 我有一个约会,但只能保持很短的时间。 sp_executesql 的问题在于它必须转到 OUTPUT 参数,而且除了 INT 变量之外,我不能将结果分配给任何东西。 我需要表中存储代码的两个日期。

如果有办法做到这一点,并且只返回本质上相当于一个小表结果的内容,那将是理想的。

感谢任何可以为我指明正确方向的人。

因此,至少在 ADO 中,如果您不关闭数据读取器,您将永远无法取回您的输出参数。 在您的示例中,这应该足以满足您的需求:

    string begin;
    string end;
    var sql = $"exec [dbo].[GetDateRange] @ID, @BeginDate OUTPUT, @EndDate OUTPUT";

    using (var dr = context.Database.ExecuteSqlQuery(sql, ID, _beginDate, _endDate))
    {
        while (dr.DbDataReader.Read())
        {
            var thing = dr.DbDataReader[0].ToString();
        }
        dr.DbDataReader.Close();
        begin = _beginDate.Value.ToString();
        end = _endDate.Value.ToString();
    }

然而, 这里提到了一个有趣的解决方案,它似乎可以解决您的痛点。

所以看起来我不需要使用 sp_executesql 也不需要任何 OUT 参数。

因此,我将存储过程更改为此,并对表中保存的底层查询进行了细微更改,以删除其中的选择,从而基本上允许在存储过程中构建 sql。

ALTER PROCEDURE [dbo].[GetDateRange] 
@ID INT

AS BEGIN SET NOCOUNT ON; DECLARE @Query1 NVARCHAR(1000) DECLARE @Query2 NVARCHAR(1000) SELECT @Query1 = BeginDate,@Query2 = EndDate FROM DateRange WHERE ID = @ID

DECLARE @Test NVARCHAR(1000) = 'SELECT ' + @Query1 + ' AS BeginDate, ' + @Query2 + ' AS EndDate'
EXECUTE (@Test)

结尾

然后我能够使用现有代码执行以下操作:

        var ID = new SqlParameter("ID", 1)
        {
            Direction = ParameterDirection.Input,
            DbType = DbType.Int32,
            Size = 500
        };

        DataTable dates = new DataTable();
        var sql = $"exec [dbo].[GetDateRange] @ID";

        using (var dr = context.Database.ExecuteSqlQuery(sql, ID))
        {
                dates.Load(dr.DbDataReader);
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM