Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET核心实体框架调用存储过程_C#_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# 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]

我正在使用ASP.NET核心实体框架,我想调用一个简单的存储过程

我在迁移中创建了存储过程,如下所示:

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,我建议您观看此视频