ASP.NET 核心 3.1:将存储过程与视图模型一起使用

ASP.NET Core 3.1 : using stored procedures with view model

下面的代码用于 运行 存储过程和 return 值(行)到 var ReturnedRowsFromSP:

var recordValue = new SqlParameter("@thisRecordValue", RecordValueFromInput);

var ReturnedRowsFromSP = _context.ReturnedRowsTableExistsInDB.FromSqlRaw("exec sp_MySpReturnsManyRows @thisRecordValue", recordValue)
                                 .AsNoTracking().ToList();

我的问题是,我需要创建一个 class,进行迁移并将 table (ReturnedRowsTableExistsInDB) 添加到数据库中,以便使用存储过程和class 需要与存储过程中的 returned 列完全相同。

有没有什么方法可以将存储过程与 table(不是在数据库中创建的)或视图模型一起使用,甚至可以将(存储过程的)结果传递给 ViewBagViewData?

非常感谢

您可以将 viewmodel 定义为 DbContext class 中的 DbSet 并忽略创建 table。试试吧

public class DbContext : DbContext
{
    public DbSet<StoredProcedureViewModel> spVM { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Ignore<StoredProcedureViewModel>();
    }
}

注意 : 在OnModelCreating中你可以忽略classDbSet创建数据库Table.

您可以参考以下步骤使用EF core查询存储过程(无需为存储过程结果创建table)。

  1. 在 SQL 服务器数据库中创建存储过程:

     CREATE PROCEDURE sp_GetBookAuthors @bookname nvarchar(250)
     AS
    
     select b.Id, b.BookName, a.AuthorName, b.ISBN from Authors as a 
              join BookAuthors as ba 
              on a.Id = ba.AuthorId 
              join Books as b 
              on ba.BookId = b.Id
              where b.BookName = @bookname
    
  2. 根据查询结果创建如下ViewModel:

     public class BookAuthorViewModel
     {
         [Key]
         public int Id { get; set; }
         public string BookName { get; set; }
         public string AuthorName { get; set; }
         public string ISBN { get; set; }
     }
    
  3. 在数据库上下文 OnModelCreating 方法中注册存储过程:

     public class WebApplication2Context : IdentityDbContext<WebApplication2User>
     { 
         public DbSet<Book> Books { get; set; }
         public DbSet<Author> Authors { get; set; }
         public DbSet<BookAuthor> BookAuthors { get; set; } 
    
         public WebApplication2Context(DbContextOptions<WebApplication2Context> options)
             : base(options)
         {
         }
    
         protected override void OnModelCreating(ModelBuilder builder)
         {
             base.OnModelCreating(builder);
             builder.Entity<BookAuthor>().HasKey(sc => new { sc.AuthorId, sc.BookId });
    
             #pragma warning disable CS0618 // Type or member is obsolete
             builder.Ignore<BookAuthorViewModel>(); //ignore create the table for the stored procedure
             builder.Query<BookAuthorViewModel>();  //register stored procedure.
             #pragma warning restore CS0618 // Type or member is obsolete
         }
    
         //create a method for the stored procedure.
         public List<BookAuthorViewModel> GetBookAuthors(string sqlQuery)
         {
             // Initialization.  
             List<BookAuthorViewModel> lst = new List<BookAuthorViewModel>();
    
             try
             { 
                 #pragma warning disable CS0618 // Type or member is obsolete
                 lst = this.Query<BookAuthorViewModel>().FromSqlRaw<BookAuthorViewModel>(sqlQuery).ToList();
                 #pragma warning restore CS0618 // Type or member is obsolete
             }
             catch (Exception ex)
             {
                 throw ex;
             }
             // Info.  
             return lst;
         }
     }
    
  4. 从控制器操作方法调用存储过程方法:

     public class HomeController : Controller
     {
         private readonly ILogger<HomeController> _logger;
         private readonly WebApplication2Context _dbcontext;
    
         public HomeController(ILogger<HomeController> logger, WebApplication2Context context)
         {
             _logger = logger;
             _dbcontext = context;
         }
    
         public IActionResult BookAuthorIndex()
         { 
             // Processing.  
             string sqlQuery = "execute sp_GetBookAuthors @bookname = 'Book A'";
             var result = _dbcontext.GetBookAuthors(sqlQuery);
             return View(result);
         }
    

结果如下: