1

我正在使用 ASP NET core 5.0 并使用 Pomelo 来处理 MariaDB 数据库

我有一个存储过程,它接受一堆参数并返回一个 SELECT COUNT(*),所以是一个很好的简单整数。我认为这将是相当微不足道的,但事实证明这实际上非常困难

我可以通过执行以下操作来做一个非常丑陋的解决方法:

Database.GetDbConnection().Open();

using (var x = Database.GetDbConnection().CreateCommand())
{
    x.CommandText = "test";
    x.CommandType = System.Data.CommandType.StoredProcedure;

    var q = await x.ExecuteScalarAsync();

    Console.WriteLine(q);
}

但我真的不想打开和关闭连接,因为这只是 janky

我以为我可以使用 Database.ExecuteSqlRaw[async],但它的返回值是受影响的行,而不是查询的实际输出。我尝试了各种获取返回值的尝试,其中大多数都抛出异常,而其他的则什么都不做。

那么,有没有一种整洁的方法可以做到这一点,还是我有一个笨拙的解决方法?

4

2 回答 2

2

这几乎是推荐的方法,只需替换Database.GetDbConnection().Open()Database.OpenConnectionAsync(),以便 EF Core 为您管理连接并在不再需要时关闭它(否则,如果 EF Core 尚未打开连接,您会突然负责稍后关闭它)。

将所有内容放在扩展方法中以便于重用并继续:

public static async Task<T> GetScalarStoredProcedureResultAsync<T>(
    this DbContext context,
    string name)
{
    await context.Database.OpenConnectionAsync();
    var connection = context.Database.GetDbConnection();

    using var command = connection.CreateCommand();
    command.CommandText = name;
    command.CommandType = System.Data.CommandType.StoredProcedure;

    return (T) await command.ExecuteScalarAsync();
}

电话是:

var count = yourContext.GetScalarStoredProcedureResultAsync<long>("test");
Console.WriteLine(count);
于 2021-05-29T09:17:00.913 回答
0

编辑

哇,刚刚意识到你已经这样做了。但是,是的,你没有打开一个新的连接。EF 仍在管理连接。您可以修改存储过程以使用输出参数,或保持原样。

原始答案

您不必手动打开新连接。使用附加到上下文的连接对象。这是从另一个 SO 答案中提取的:

using (var cmd = _context.Database.GetDbConnection().CreateCommand()) {
    cmd.CommandText = "[Production].[Select_TicketQuantity]";
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    if (cmd.Connection.State != System.Data.ConnectionState.Open) cmd.Connection.Open();
    cmd.Parameters.Add(new SqlParameter("Ticket", ticket));
    cmd.Parameters.Add(new SqlParameter("Reference", reference));
    quantity = (int)cmd.ExecuteScalar();
}

在这里查看答案:https ://stackoverflow.com/a/59627588/12431728

于 2021-05-29T04:22:48.910 回答