如何使用Pomelo/Entity从存储过程中获取SELECT COUNT(*)的结果



我使用的是ASP.NET核心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);
}

但我真的不想打开和关闭连接,因为这只是一个糟糕的

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

那么,有没有一个整洁的方法来做到这一点,或者我有一个笨拙的变通方法?

这几乎是建议的方法,只需将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);

编辑

哇,刚刚意识到你已经在这么做了。但是,是的,你没有打开一个新的连接。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

最新更新