如何使用 Pomelo/Entity 从存储过程中获取 SELECT COUNT(*) 的结果
How to get the result of SELECT COUNT(*) from a stored procedure using Pomelo/Entity
我正在使用 ASP NET 核心 5.0 并使用 Pomelo 来处理 MariaDB 数据库
我有一个存储过程,它接受一堆参数和 return 一个 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],但 return 值是受影响的行,而不是查询的实际输出。我已经尝试了各种尝试来获得 return 值,其中大多数都抛出异常,而其他人则什么都不做。
那么,有没有一种简洁的方法可以做到这一点,或者我有一个笨拙的解决方法吗?
编辑
哇,刚刚意识到你已经在这样做了。但是,是的,您没有打开新连接。 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();
}
在这里查看答案:
这几乎是推荐的方法,只需将 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);
我正在使用 ASP NET 核心 5.0 并使用 Pomelo 来处理 MariaDB 数据库
我有一个存储过程,它接受一堆参数和 return 一个 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],但 return 值是受影响的行,而不是查询的实际输出。我已经尝试了各种尝试来获得 return 值,其中大多数都抛出异常,而其他人则什么都不做。
那么,有没有一种简洁的方法可以做到这一点,或者我有一个笨拙的解决方法吗?
编辑
哇,刚刚意识到你已经在这样做了。但是,是的,您没有打开新连接。 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();
}
在这里查看答案:
这几乎是推荐的方法,只需将 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);