C# ASP.NET核心实体框架调用存储过程
我正在使用ASP.NET核心实体框架,我想调用一个简单的存储过程 我在迁移中创建了存储过程,如下所示:C# ASP.NET核心实体框架调用存储过程,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,我正在使用ASP.NET核心实体框架,我想调用一个简单的存储过程 我在迁移中创建了存储过程,如下所示: public partial class spGetAvailableCourses : Migration { protected override void Up(MigrationBuilder migrationBuilder) { var sp = @"CREATE PROCEDURE [dbo].[GetAvailableCourses]
public partial class spGetAvailableCourses : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
var sp = @"CREATE PROCEDURE [dbo].[GetAvailableCourses]
AS
BEGIN
SELECT COUNT(courses.Enrolled) FROM Courses WHERE Courses.Capacity > Courses.Enrolled;
END";
migrationBuilder.Sql(sp);
}
我可以使用以下命令调用SQL Server中的存储过程
EXEC dbo.GetAvailableCourses
但是,当我尝试在我的ICourseRepository
中调用存储过程时,它不起作用,返回的是-1
有人能告诉我调用存储过程的正确方法吗?谢谢
public class CourseRepository : ICourseRepository
{
private readonly DataContext _context;
public CourseRepository(DataContext context)
{
_context = context;
}
public Task<CoursesAvailableCount> CoursesAvailableCount()
{
var ss = _context.Database.ExecuteSqlRaw("GetAvailableCourses");
return null;
}
公共类课程存储库:ICourseRepository
{
私有只读数据上下文_上下文;
公共课程假设(数据上下文)
{
_上下文=上下文;
}
公共任务课程可用计数()
{
var ss=_context.Database.ExecuteSqlRaw(“GetAvailableCourses”);
返回null;
}
我也试过了
public async Task<CoursesAvailableCount> CoursesAvailableCount()
{
var s = await _context.Database.ExecuteSqlCommandAsync("GetAvailableCourses");
}
public异步任务courseAvailableCount()
{
var s=await_context.Database.ExecuteSqlCommandAsync(“GetAvailableCourses”);
}
除了ExecuteSqlCommand方法外,DbContext.Database属性还提供了一个API,允许您直接执行ADO.NET操作。GetDbConnection方法返回一个代表上下文基础连接的DbConnection对象。从这一点上,您可以恢复到熟悉的ADO.NET API:
使用(var命令=_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText=“SP_NAME”;
command.CommandType=CommandType.storedProcess;
_context.Database.OpenConnection();
使用(var result=command.ExecuteReader())
{
if(result.HasRows)
{
result.Read();
var x=result.GetInt32(0);//x=您的sp计数值
}
}
}
编辑(扩展示例):
除了ExecuteSqlCommand方法外,DbContext.Database属性还提供了一个API,允许您直接执行ADO.NET操作。GetDbConnection方法返回一个表示上下文基础连接的DbConnection对象。从这一点上,您可以恢复到熟悉的ADO.NET API:
使用(var命令=_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText=“SP_NAME”;
command.CommandType=CommandType.storedProcess;
_context.Database.OpenConnection();
使用(var result=command.ExecuteReader())
{
if(result.HasRows)
{
result.Read();
var x=result.GetInt32(0);//x=您的sp计数值
}
}
}
编辑(扩展示例):
对于.NETCore3.1,使用带参数的存储过程。使用下面的代码。它适合我。享受
using (var command = DbContext.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "Users_SP";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter(“@usernme”, username));
command.Parameters.Add(new SqlParameter("@TransDate", DateTime.Now));
DbContext..Database.OpenConnection();
using (var result = command.ExecuteReader())
{
if (result.HasRows)
{
while (result.Read())
{
response = Convert.ToString(result["Amount"]);
}
}
}
}
对于.NETCore3.1,使用带参数的存储过程。使用下面的代码。它适合我。享受
using (var command = DbContext.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "Users_SP";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter(“@usernme”, username));
command.Parameters.Add(new SqlParameter("@TransDate", DateTime.Now));
DbContext..Database.OpenConnection();
using (var result = command.ExecuteReader())
{
if (result.HasRows)
{
while (result.Read())
{
response = Convert.ToString(result["Amount"]);
}
}
}
}
检查它是否显示“结果必须是实体类型。这意味着存储过程必须返回实体对应表的所有列。”这是否意味着由于我返回的是一个整数,所以无法执行此操作?
ExecuteSqlRaw
返回受影响的行数。调用计数结果是错误的方法。为什么不使用纯EF lambda或linq语句呢?这很容易根据问题中的sql代码编写。作为旁注:是否应该保留SP然后,我会将GetAvailableCourses
重命名为GetAvailableCourseCount
,因为如果除了名称之外我对该SP一无所知,我会从GetAvailableCourses
中获得一个课程列表。检查它是否显示“结果必须是实体类型。这意味着存储过程必须返回实体对应表的所有列。"这是否意味着由于我返回的是一个整数,所以无法执行此操作?ExecuteSqlRaw
返回受影响的行数。调用计数结果是错误的方法。为什么不使用纯EF lambda或linq语句呢?这很容易根据问题中的sql代码编写。作为旁注:是否应该保留SP然后我会将GetAvailableCourses
重命名为GetAvailableCourseCount
,因为如果我除了名称之外对该SP一无所知,我会从GetAvailableCourses
中获得一个课程列表。谢谢AliReza。这很有效。我以前从未使用过ADO.Net,但有更好的方法来编写结果。hasRow?我将重新发布还有,我应该为dbconnection做一个finally i close吗?EntityFramework Core没有SqlQuery
函数,所以这是处理无法映射到实体的自定义SP的唯一方法。顺便说一句,直接使用ADO没有错。EF在内部使用它。您可以创建一个扩展方法并轻松使用它。最后一个问题在上,是否建议使用命令.ExecuteReaderAsync()代替命令.ExecuteReader?是的,当我有一个可能的阻塞任务时,我总是使用异步函数。你问到HasRow,如果你不熟悉DataReaderObject,我建议你看这个视频,谢谢AliReza。这很有效。我以前从未使用过ADO.Net,但有没有更好的方法来编写result.HasRow?我会仔细阅读。also我应该为dbconnection执行最终关闭吗?EntityFramework Core没有SqlQuery
函数,因此这是处理无法映射到实体的自定义SP的唯一方法。顺便说一句,直接使用ADO没有什么问题。EF在内部使用此方法。您可以创建一个扩展方法并轻松使用它。最后一个问题是,您是否可以使用命令.ExecuteReaderAsync()而不是命令.ExecuteReader?是的,当我有一个可能的阻塞任务时,我总是使用异步函数。如果您询问HasRow,如果您不熟悉DataReaderObject,我建议您观看此视频