Sql server C#:如何使用实体框架核心将记录检索到存储过程中?

Sql server C#:如何使用实体框架核心将记录检索到存储过程中?,sql-server,asp.net-mvc-4,c#-4.0,entity-framework-core,Sql Server,Asp.net Mvc 4,C# 4.0,Entity Framework Core,我用Angular创建了一个新的ASP.NET Core 2.1 web应用程序 Visual Studio创建了一个使用实体框架核心和ASP.NET核心MVC的项目 我有一个问题:我必须从存储过程中读取记录: CREATE PROCEDURE GetEmployees (@PageIndex INT, @PageSize INT) AS BEGIN SELECT * FROM employee ORDER BY id OFFSET

我用Angular创建了一个新的ASP.NET Core 2.1 web应用程序

Visual Studio创建了一个使用实体框架核心和ASP.NET核心MVC的项目

我有一个问题:我必须从存储过程中读取记录:

CREATE PROCEDURE GetEmployees
    (@PageIndex INT,
     @PageSize INT)
AS
BEGIN
    SELECT * 
    FROM employee 
    ORDER BY id 
        OFFSET @PageSize * (@PageIndex - 1) ROWS 
        FETCH NEXT @PageSize ROWS ONLY;

    SELECT COUNT(*) AS totalCount 
    FROM employee;
END
我发现了,但不幸的是仍然有一些东西不起作用

这是我的代码:

namespace Angular.Controllers
{
    //[Produces("application/json")]
    [Route("api/Employees")]
    public class EmployeesController : Controller
    {
        private readonly ApplicationDbContext _context;

        public EmployeesController(ApplicationDbContext context)
        {
            _context = context;
        }

        // GET: api/Employees/pageIndex/1/pageSize/1
        [HttpGet("pageIndex/{pageIndex}/pageSize/{pageSize}")]
        public Task<IActionResult> GetEmployeeP([FromRoute] int pageIndex, int pageSize)
        {
            SqlParameter pageIndexParam = new SqlParameter("@PageIndex", SqlDbType.Int);
            pageIndexParam.Value = pageIndex;

            SqlParameter pageSizeParam = new SqlParameter("@pageSize", SqlDbType.Int);
            pageSizeParam.Value = pageSize;

            // SqlParameter pageIndexParam = new SqlParameter("@PageIndex", pageIndex);
            // SqlParameter pageSizeParam = new SqlParameter("@pageSize", pageSize);

            var cmd = _context.Database.GetDbConnection().CreateCommand();
            cmd.CommandText = "GetEmployees"; // The name of the stored procedure
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            // the 2 parameters to be passed to the procedure
            var param = cmd.CreateParameter();
            param.ParameterName = "@PageIndex";
            param.Value = pageIndexParam;
            cmd.Parameters.Add(param);

            var param2 = cmd.CreateParameter();
            param2.ParameterName = "@pageSize";
            param2.Value = pageSizeParam;
            cmd.Parameters.Add(param2);

            try
            {
                // connection.Open();
                // _context.Database.GetDbConnection().Open(); // it crashes after this line
                _context.Database.OpenConnection(); // it crashes after this line
                var dr = cmd.ExecuteReader(); // ArgumentException: No mapping exists from object type System.Data.SqlClient.SqlParameter to a known managed provider native type.
                List<Employee> listEmp = new List<Employee>();

                while (dr.Read())
                {
                    // Is there a faster way to read the whole record?
                    // Or should I write a line for each field?
                    Employee emp = new Employee();
                    emp.ID = System.Int32.Parse(dr["id"].ToString());
                    emp.Fname = dr["FName"].ToString();
                    emp.email = dr["email"].ToString();
                    emp.Lname = dr["LName"].ToString();
                    listEmp.Add(emp);

                    dr.NextResult();
                }

                return Ok(listEmp);
            }
            catch (Exception ex)
            {
                // how can I return an error in json format?
                throw;
            }
        }
    }
}
namespace.Controllers
{
//[产生(“应用程序/json”)]
[路线(“api/员工”)]
公共类EmployeesController:控制器
{
私有只读应用程序的bContext\u上下文;
公共雇员控制器(ApplicationDbContext上下文)
{
_上下文=上下文;
}
//获取:api/Employees/pageIndex/1/pageSize/1
[HttpGet(“pageIndex/{pageIndex}/pageSize/{pageSize}”)]
公共任务GetEmployeeP([FromRoute]int pageIndex,int pageSize)
{
SqlParameter pageIndexParam=新的SqlParameter(“@PageIndex”,SqlDbType.Int);
pageIndexParam.Value=pageIndex;
SqlParameter pageSizeParam=新的SqlParameter(“@pageSize”,SqlDbType.Int);
pageSizeParam.Value=pageSize;
//SqlParameter pageIndexParam=新的SqlParameter(“@PageIndex”,PageIndex);
//SqlParameter pageSizeParam=新的SqlParameter(“@pageSize”,pageSize);
var cmd=_context.Database.GetDbConnection().CreateCommand();
cmd.CommandText=“GetEmployees”;//存储过程的名称
cmd.CommandType=System.Data.CommandType.StoredProcess;
//要传递给过程的2个参数
var param=cmd.CreateParameter();
param.ParameterName=“@PageIndex”;
参数值=pageIndexParam;
cmd.Parameters.Add(param);
var param2=cmd.CreateParameter();
param2.ParameterName=“@pageSize”;
param2.Value=pageSizeParam;
cmd.Parameters.Add(param2);
尝试
{
//connection.Open();
//_context.Database.GetDbConnection().Open();//在这一行之后崩溃
_context.Database.OpenConnection();//它在这一行之后崩溃

var dr=cmd.ExecuteReader();//ArgumentException:不存在从对象类型System.Data.SqlClient.SqlParameter到已知托管提供程序本机类型的映射。 List listEmp=新列表(); while(dr.Read()) { //有没有更快的方法来读取整个记录? //还是应该为每个字段写一行? 员工emp=新员工(); emp.ID=System.Int32.Parse(dr[“ID”].ToString()); emp.Fname=dr[“Fname”].ToString(); emp.email=dr[“email”].ToString(); emp.Lname=dr[“Lname”].ToString(); 列表添加(emp); NextResult博士(); } 返回Ok(listEmp); } 捕获(例外情况除外) { //如何以json格式返回错误? 投 } } } }
问题出在脚本执行器的行中:


ArgumentException:不存在从对象类型System.Data.SqlClient.SqlParameter到已知托管提供程序本机类型的映射。

我使用Microsoft SQL Server 在Startup.cs文件中,我以以下方式配置了连接:

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer("Server=localhost\\SQLEXPRESS;Database=master;Trusted_Connection=True;"));
services.AddDbContext(options=>options.UseSqlServer(“Server=localhost\\SQLEXPRESS;Database=master;Trusted\u Connection=True;”);
你能帮我吗

也许我成功地正确地传递了参数(请参见答案中的我的解决方案),但我无法根据答案提取记录,你能试试吗

     public Task<IActionResult> GetEmployeeP([FromRoute] int pageIndex, int pageSize)
    {
        var cmd = _context.Database.GetDbConnection().CreateCommand();
        cmd.CommandText = "GetEmployees";
        cmd.CommandType = System.Data.CommandType.StoredProcedure;

        cmd.Parameters.AddWithValue("@PageIndex", pageIndex);
        cmd.Parameters.AddWithValue("@PageSize", pageSize);

        try
        {
          //...
        }
   }
公共任务GetEmployeeP([FromRoute]int pageIndex,int pageSize) { var cmd=_context.Database.GetDbConnection().CreateCommand(); cmd.CommandText=“GetEmployees”; cmd.CommandType=System.Data.CommandType.StoredProcess; cmd.Parameters.AddWithValue(“@PageIndex”,PageIndex); cmd.Parameters.AddWithValue(“@PageSize”,PageSize); 尝试 { //... } }
如果有什么事情发生,请告诉我。

部分解决的谜题:

    // GET: api/Employees/pageIndex/1/pageSize/1
    [HttpGet("pageIndex/{pageIndex}/pageSize/{pageSize}")]
    public async Task<IActionResult> GetEmployeeP([FromRoute] int pageIndex, int pageSize)
    {
        _context.Database.OpenConnection();

        var cmd = _context.Database.GetDbConnection().CreateCommand();
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        /*
         * it's the same, it also works with these lines
                    SqlParameter pageIndexParam = new SqlParameter("PageIndex", pageIndex);
                    SqlParameter pageSizeParam = new SqlParameter("PageSize", pageSize);
                    cmd.Parameters.Add(pageIndexParam);
                    cmd.Parameters.Add(pageSizeParam);
        */

        cmd.CommandText = "GetEmployees"; // The name of the stored procedure

        // the 2 parameters to be passed to the procedure
        var param = cmd.CreateParameter();
        param.ParameterName = "@PageIndex";
        param.Value = pageIndex;
        cmd.Parameters.Add(param);

        var param2 = cmd.CreateParameter();
        param2.ParameterName = "@PageSize";
        param2.Value = pageSize;
        cmd.Parameters.Add(param2);




        try
        {
            System.Data.Common.DbDataReader dr = cmd.ExecuteReader();
            List<Employee> listEmp = new List<Employee>();

            while (dr.Read())
            {
                // Is there a faster way to read the whole record?
                // Or should I write a line for each field?
                Employee emp = new Employee();
                //emp.ID = System.Int32.Parse(dr["id"].ToString());
                emp.ID = 1; //  it crashes after this line
                emp.Fname = dr["FName"].ToString(); // System.IndexOutOfRangeException: FName

                /*
                 * it doesn't see the columns :-(
                                    emp.email = dr["email"].ToString();
                                    emp.Lname = dr["LName"].ToString();
                */
                listEmp.Add(emp);
                dr.NextResult();
            }
            return Ok(listEmp);
        }
        catch (Exception ex)
        {
            // how can I return an error in json format?
            throw;
        }



    }
System.indexootfrangeexception:FName


它没有看到列:-(

我在当前项目中使用EntityFramework核心,并使用以下方法通过存储过程获取数据

首先,在存储过程中创建一个具有相同数量和名称的属性的模型

假设您仅通过存储过程选择EmployeeName、EmployeeId

模型

 public class EmployeeModel
  {
    public string EmployeeName { get; set; }
    public int EmployeeId{ get; set; }
  }
转到Db上下文文件并注册自定义模型

 public partial class ApplicationDbContext: DbContext
 {
 public virtual DbSet<EmployeeModel> EmployeeModel{ get; set; }
 protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<EmployeeModel>(entity =>
        { 
        });
        }
    }
public分部类ApplicationDbContext:DbContext
{
公共虚拟DbSet EmployeeModel{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity(Entity=>
{ 
});
}
}
你的控制器

 [HttpGet("pageIndex/{pageIndex}/pageSize/{pageSize}")]
    public Task<IActionResult> GetEmployeeP([FromRoute] int pageIndex, int pageSize)
    {
    List<EmployeeModel> employeeList = new List<EmployeeModel>();
    employeeList = _context.EmployeeModel.FromSql("GetEmployees 
    @PageIndex,@PageSize", 
    new SqlParameter("@PageIndex", pageIndex),
    new SqlParameter("@PageSize", pageSize)).ToList();
    return Ok(employeeList);
    }
[HttpGet(“pageIndex/{pageIndex}/pageSize/{pageSize}”)]
公共任务GetEmployeeP([FromRoute]int pageIndex,int pageSize)
{
List employeeList=新列表();
employeeList=\u context.EmployeeModel.FromSql(“GetEmployees
@PageIndex,@PageSize“,
新的SqlParameter(“@PageIndex”,PageIndex),
新的SqlParameter(“@PageSize”,PageSize)).ToList();
返回Ok(员工列表);
}

出现什么错误?可能连接已打开?ArgumentException:不存在从对象类型System.Data.SqlClient.SqlParameter到已知托管提供程序本机类型的映射。创建
SqlParameter
对象时,请尝试指定数据类型并设置
 [HttpGet("pageIndex/{pageIndex}/pageSize/{pageSize}")]
    public Task<IActionResult> GetEmployeeP([FromRoute] int pageIndex, int pageSize)
    {
    List<EmployeeModel> employeeList = new List<EmployeeModel>();
    employeeList = _context.EmployeeModel.FromSql("GetEmployees 
    @PageIndex,@PageSize", 
    new SqlParameter("@PageIndex", pageIndex),
    new SqlParameter("@PageSize", pageSize)).ToList();
    return Ok(employeeList);
    }