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(不是在数据库中创建的)或视图模型一起使用,甚至可以将(存储过程的)结果传递给 ViewBag
或 ViewData
?
非常感谢
您可以将 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
中你可以忽略class
或DbSet
创建数据库Table.
您可以参考以下步骤使用EF core查询存储过程(无需为存储过程结果创建table)。
在 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
根据查询结果创建如下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; }
}
在数据库上下文 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;
}
}
从控制器操作方法调用存储过程方法:
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);
}
结果如下:
下面的代码用于 运行 存储过程和 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(不是在数据库中创建的)或视图模型一起使用,甚至可以将(存储过程的)结果传递给 ViewBag
或 ViewData
?
非常感谢
您可以将 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
中你可以忽略class
或DbSet
创建数据库Table.
您可以参考以下步骤使用EF core查询存储过程(无需为存储过程结果创建table)。
在 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
根据查询结果创建如下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; } }
在数据库上下文 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; } }
从控制器操作方法调用存储过程方法:
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); }
结果如下: