本节将会介绍在掌握开发基础 ASP.NET Core web 应用程序之后使用 Entity Framework Core 开发时需要注意的几个问题。
原生 SQL 查询
在 EF Core 1.0 中具有以下选项:
-
返回的对象必须是
DbSet对象期望的类型,并且它们会自动跟踪数据库上下文中除非你手动关闭跟踪。 -
对于非查询命令使用
Database.ExecuteSqlCommand。
数据库上下文不会跟踪返回的数据,即使你使用该方法来检索实体类型也是如此。
在本教程中,将用户输入集成到查询中时会使用参数化查询。
调用返回实体的查询
若要查看实现细节,你需要更改部门控制器中Details方法的代码。
在DepartmentsController.cs中的Details方法,通过代码调用FromSql方法检索一个部门,如以下高亮代码所示:
1 public async Task<IActionResult> Details(int? id) 2 { 3 if (id == null) 4 { 5 return NotFound(); 6 } 7 8 string query = "SELECT * FROM Department WHERE DepartmentID = {0}"; 9 var department = await _context.Departments 10 .FromSql(query, id) 11 .Include(d => d.Administrator) 12 .AsNoTracking() 13 .SingleOrDefaultAsync(); 14 15 if (department == null) 16 { 17 return NotFound(); 18 } 19 20 return View(department); 21 }
为了验证新代码是否工作正常,请选择Department选项卡,然后点击某个部门的Detail。
调用返回其他类型的查询
在 EF Core 1.0 中,执行该操作的另一种方法是编写 ADO.NET 代码,并从 EF 获取数据库连接。
在HomeController.cs中,将About方法替换为以下代码:
public async Task<ActionResult> About() { List<EnrollmentDateGroup> groups = new List<EnrollmentDateGroup>(); var conn = _context.Database.GetDbConnection(); try { await conn.OpenAsync(); using (var command = conn.CreateCommand()) { string query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount " + "FROM Person " + "WHERE Discriminator = 'Student' " + "GROUP BY EnrollmentDate"; command.CommandText = query; DbDataReader reader = await command.ExecuteReaderAsync(); if (reader.HasRows) { while (await reader.ReadAsync()) { var row = new EnrollmentDateGroup { EnrollmentDate = reader.GetDateTime(0), StudentCount = reader.GetInt32(1) }; groups.Add(row); } } reader.Dispose(); } } finally { conn.Close(); } return View(groups); }
添加 using 语句:
using System.Data.Common;
显示的数据和之前一样。
调用更新查询
页面外观类似于下图:
在 CoursesContoller.cs 中,为 HttpGet 和 HttpPost 添加 UpdateCourseCredits 方法:
public IActionResult UpdateCourseCredits() { return View(); }
[HttpPost] public async Task<IActionResult> UpdateCourseCredits(int? multiplier) { if (multiplier != null) { ViewData["RowsAffected"] = await _context.Database.ExecuteSqlCommandAsync( "UPDATE Course SET Credits = Credits * {0}", parameters: multiplier); } return View(); }
中不会返回任何东西,并且在视图中显示一个空文本框和提交按钮,如上图所示。
当视图获取RowsAffected值,它将显示更新的行数。
在“解决方案资源管理器”中,右键单击“Views/Courses”文件夹,然后依次单击“添加”和“新建项”。
在添加新项对话框中,在已安装下单击ASP.NET,在左窗格中,单击MVC 视图页,并将新视图命名为UpdateCourseCredits.cshtml。
在Views/Courses/UpdateCourseCredits.cshtml中,将模板代码替换为以下代码:
@{ ViewBag.Title = "UpdateCourseCredits"; } <h2>Update Course Credits</h2> @if (ViewData["RowsAffected"] == null) { <form asp-action="UpdateCourseCredits"> <div class="form-actions no-color"> <p> Enter a number to multiply every course's credits by: @Html.TextBox("multiplier") </p> <p> <input type="submit" value="Update" class="btn btn-default" /> </p> </div> </form> } @if (ViewData["RowsAffected"] != null) { <p> Number of rows updated: @ViewData["RowsAffected"] </p> } <div> @Html.ActionLink("Back to List", "Index") </div>