使用ASP.NET Core MVC 和 Entity Framework Core 開發一個CRUD(增刪改查)的應用程序
不定時更新翻譯系列,此系列更新毫無時間規律,文筆菜翻譯菜求各位看官老爺們輕噴,如覺得我翻譯有問題請挪步原博客地址
本文打算使用Entity Framework Core解釋ASP.NET Core MVC中的基本創建,讀取,更新和刪除(CRUD)操作。我們使用Entity Framework Code First的方法開發應用程序 ,要設置ASP.NET Core MVC應用程序的開發環境,我們遵循本文中開始使用 ASP.NET Core MVC.的步驟。應用程序使用一個名為Book的實體來執行CRUD操作,並做一些簡單的演示。
更多精彩內容
創建數據庫
這個應用程序采用的是Entity Framework Core 中的Code First(代碼優先)方法,所以我們首先要添加Entity Framework Core ,這個應用程序使用的是SQL Server數據庫,因此我們需要提供SQL Server數據庫程序該,提供程序可通過名為 Microsoft.EntityFrameworkCore.SqlServer的 NuGet軟件包提供。當應用程序創建時,它包括Microsoft.AspNetCore.All NuGet元包。此包還包括Microsoft.EntityFrameworkCore.SqlServer,因此我們不必安裝它。
創建數據實體模型
應用程序在單個實體上執行CRUD操作,但是現在我們創建了兩個實體,這些實體分別是BaseEntity和Book。BaseEntity類具有公共屬性,,是其他實體的父類,並將由其他實體繼承。BaseEntity類按照下面的代碼片段創建。
using System;
namespace FirstCRUDApplication.DbEntities
{
public class BaseEntity
{
public Int64 Id { get; set; }
public DateTime AddedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string IPAddress { get; set; }
}
}
應用程序在名為Book的實體上執行CRUD操作。現在,我們創建一個Book類並繼承BaseEntity。
namespace FirstCRUDApplication.DbEntities
{
public class Book:BaseEntity
{
public string Name { get; set; }
public string ISBN { get; set; }
public string Author { get; set; }
public string Publisher { get; set; }
}
}
現在,讓我們為Book實體定義配置。數據庫表將使用Book實體的配置創建。定義配置有兩種選擇,一種是數據注釋 ,另一種是Fluent API。遵循SRP原則,我們使用第二個選項Fluent API定義實體配置。下面是BookMap類的代碼片段
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace FirstCRUDApplication.DbEntities
{
public class BookMap
{
public BookMap(EntityTypeBuilder<Book> entityBuilder)
{
entityBuilder.HasKey(t => t.Id);
entityBuilder.Property(t => t.Name).IsRequired();
entityBuilder.Property(t => t.ISBN).IsRequired();
entityBuilder.Property(t => t.Author).IsRequired();
entityBuilder.Property(t => t.Publisher).IsRequired();
}
}
}
EntityTypeBuilder<T>支持Entity Framework Core的基礎結構。T表示被配置的實體。它使用方法定義每個字段的配置。讓我們看一下在前面的代碼中使用的一些方法。
- **HasKey: **
它設置了構成主鍵的實體屬性。 - Property: 它返回一個可以用來配置實體類型屬性的對象。
現在,我們創建了名為CRUDContext的上下文類。它繼承自DbContext。它是實體和數據庫之間的橋梁。它是一個主要類,它將數據作為對象進行交互。我們在上下文類中重寫OnModelCreating方法。當我們使用Fluent API時,它定義了實體如何映射到數據庫。下面是名為CRUDContext.cs的上下文類的代碼片段。
using Microsoft.EntityFrameworkCore;
namespace FirstCRUDApplication.DbEntities
{
public class CRUDContext:DbContext
{
public CRUDContext(DbContextOptions<CRUDContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
new BookMap(modelBuilder.Entity<Book>());
}
}
}
使用EF連接數據庫
我們定義了一個帶有上下文的數據模型。現在,我們定義了數據庫和上下文之間的連接。我們必須遵循以下步驟,在應用程序中使用上下文。
- 我們定義一個連接字符串,以便將上下文連接到數據庫。打開appsetting.json文件,並根據以下代碼片段定義連接字符串。
"ConnectionStrings": {
"DefaultConnection": "Data Source=DESKTOP-RG33QHE;Initial Catalog=ApplicationDb;User ID=sa; Password=admin123"
}
它類似於web.config。它存儲配置級別設置,如連接字符串、SMTP、域名等。
- 應用程序配置從
Startup類初始化。由於這個應用程序使用了Entity Framework Core,所以我們在使用中添加了兩個名稱空間。下面的代碼片段是相同的。
using FirstCRUDApplication.DbEntities;
using Microsoft.EntityFrameworkCore;
- ASP.NET Core提供了內置的控制反轉。在應用程序啟動時,上下文注冊到IoC。在此之后,使用構造函數依賴注入,上下文注入到MVC控制器中。因此,它在
Startup類中注冊為一個服務。下面的代碼片段,用於配置上下文注冊為服務的ConfigureServices方法。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<CRUDContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
使用EF 遷移初始化數據庫
我們使用Entity Framework Core Migration來根據數據模型創建一個數據庫。為了執行遷移,我們可以使用軟件包管理器控制台(PMS)和命令行界面(CLI)。
Entity Framework Core工具CLI提供了 Microsoft.EntityFrameworkCore.Tool.DotNet 。要安裝這個包,我們不能使用install-package命令或包管理器GUI。但是我們可以在應用程序中編輯.csproj文件,並將這個包添加到 DotNetCliToolReference,從而安裝這個包,下面的XML代碼是相同的。
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>
現在,我們需要遵循從數據模型創建新數據庫的步驟。這些都是
- 保存更改並構建項目。
- 打開解決方案文件夾位置。在解決方案瀏覽器中,右鍵單擊該項目並從上下文菜單中選擇打開文件資源管理器。
- 如下圖所示在地址欄中寫入cmd命令並按Enter鍵。
要發起遷移,請在命令窗口中輸入以下命令。
dotnet ef migrations添加了InitialCreate

圖1:Entity Framework Core Migration
現在,我們將遷移應用到數據庫。我們在命令窗口中輸入以下命令。該命令在其中創建數據庫和表。
dotnet ef database 修改
因此,我們在Entity Framework Core中使用code first方法創建了數據庫
創建應用程序用戶界面
現在,我們為應用程序開發用戶界面。首先,我們為應用程序UI創建名為BookViewModel 的視圖模型。這個模型與視圖緊密地結合在一起。下面的代碼片段用於視圖模型。
using System.ComponentModel.DataAnnotations;
namespace FirstCRUDApplication.Models
{
public class BookViewModel
{
public long Id { get; set; }
public string Name { get; set; }
[Display(Name = "ISBN No")]
public string ISBN { get; set; }
public string Author { get; set; }
public string Publisher { get; set; }
}
}
現在,在控制器文件夾下創建一個名為 BookController的控制器。該控制器具有執行CRUD操作的操作方法。CRUDContext類實例使用依賴注入注入它的構造函數。下面的代碼片段是一樣的。
using FirstCRUDApplication.DbEntities;
using FirstCRUDApplication.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace FirstCRUDApplication.Controllers
{
public class BookController : Controller
{
private CRUDContext context;
public BookController(CRUDContext context)
{
this.context = context;
}
[HttpGet]
public IActionResult Index()
{
IEnumerable<BookViewModel> model = context.Set<Book>().ToList().Select(b => new BookViewModel
{
Id= b.Id,
Name = b.Name,
ISBN = b.ISBN,
Author = b.Author,
Publisher = b.Publisher
});
return View("Index", model);
}
[HttpGet]
public IActionResult AddEditBook(long? id)
{
BookViewModel model = new BookViewModel();
if (id.HasValue)
{
Book book = context.Set<Book>().SingleOrDefault(c => c.Id == id.Value);
if (book != null)
{
model.Id = book.Id;
model.Name = book.Name;
model.ISBN = book.ISBN;
model.Author = book.Author;
model.Publisher = book.Publisher;
}
}
return PartialView("~/Views/Book/_AddEditBook.cshtml", model);
}
[HttpPost]
public IActionResult AddEditBook(long? id, BookViewModel model)
{
try
{
if (ModelState.IsValid)
{
bool isNew = !id.HasValue;
Book book = isNew ? new Book
{
AddedDate = DateTime.UtcNow
} : context.Set<Book>().SingleOrDefault(s => s.Id == id.Value);
book.Name = model.Name;
book.ISBN = model.ISBN;
book.Author = model.Author;
book.Publisher = model.Publisher;
book.IPAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString();
book.ModifiedDate = DateTime.UtcNow;
if (isNew)
{
context.Add(book);
}
context.SaveChanges();
}
}
catch (Exception ex)
{
throw ex;
}
return RedirectToAction("Index");
}
[HttpGet]
public IActionResult DeleteBook(long id)
{
Book book = context.Set<Book>().SingleOrDefault(c => c.Id == id);
string bookName = book.Name;
return PartialView("~/Views/Book/_DeleteBook.cshtml", model: bookName);
}
[HttpPost]
public IActionResult DeleteBook(long id, IFormCollection form)
{
Book book = context.Set<Book>().SingleOrDefault(c => c.Id == id);
context.Entry(book).State = Microsoft.EntityFrameworkCore.EntityState.Deleted;
context.SaveChanges();
return RedirectToAction("Index");
}
}
}
現在,我們為每個CRUD操作開發用戶界面。視圖為添加和編輯圖書、圖書列表和刪除圖書而創建。我們來一個個的來看視圖。
圖書清單
這是應用程序的第一個視圖。它顯示了清單中的所有書籍。它以表格格式顯示圖書數據,並有一個添加新書的選項。圖書列表有編輯和刪除圖書的選項。它是一個名為index的索引視圖.cshtml在圖書文件夾的視圖。下面的代碼片段是一樣的。
@model IEnumerable<FirstCRUDApplication.Models.BookViewModel>
@using FirstCRUDApplication.Models
@using FirstCRUDApplication.Code
<div class="top-buffer"></div>
<div class="panel panel-primary">
<div class="panel-heading panel-head">Books</div>
<div class="panel-body">
<div class="btn-group">
<a id="createEditBookModal" data-toggle="modal" asp-action="AddEditBook" data-target="#modal-action-book" class="btn btn-primary">
<i class="glyphicon glyphicon-plus"></i> Add Book
</a>
</div>
<div class="top-buffer"></div>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>ISBN</th>
<th>Author</th>
<th>Publisher</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.Name)</td>
<td>@Html.DisplayFor(modelItem => item.ISBN)</td>
<td>@Html.DisplayFor(modelItem => item.Author)</td>
<td>@Html.DisplayFor(modelItem => item.Publisher)</td>
<td>
<a id="editBookModal" data-toggle="modal" asp-action="AddEditBook" asp-route-id= "@item.Id" data-target="#modal-action-book"
class="btn btn-info">
<i class="glyphicon glyphicon-pencil"></i> Edit
</a>
<a id="deleteBookModal" data-toggle="modal" asp-action="DeleteBook" asp-route-id= "@item.Id" data-target="#modal-action-book" class="btn btn-danger">
<i class="glyphicon glyphicon-trash"></i> Delete
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
@Html.Partial("_Modal", new BootstrapModel { ID = "modal-action-book", AreaLabeledId = "modal-action-book-label", Size = ModalSize.Medium })
@section scripts
{
<script src="~/js/book-index.js" asp-append-version="true"></script>
}
現在,讓我們運行應用程序。作為第一個請求,它使用HttpGet請求調用index()的action方法,並將UI中列出的所有圖書作為響應,如圖2所示。

圖2:書清單界面
創建/編輯圖書視圖
由於創建和編輯視圖都是相同的,因此我們為這兩個視圖創建了一個公共視圖。這個視圖使用相同的BookViewModel。讓我們定義一個創建/編輯的圖書部分視圖。下面是_AddEditBook.cshtml的代碼片段。
@model FirstCRUDApplication.Models.BookViewModel
@using FirstCRUDApplication.Models
<form asp-action="AddEditBook" role="form">
@await Html.PartialAsync("_ModalHeader", new ModalHeader { Heading = String.Format("{0} Book", @Model.Id == 0 ? "Add" : "Edit") })
<div class="modal-body form-horizontal">
<div class="form-group">
<label asp-for="Name" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="Name" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="ISBN" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="ISBN" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Author" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="Author" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Publisher" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="Publisher" class="form-control" />
</div>
</div>
</div>
@await Html.PartialAsync("_ModalFooter", new ModalFooter { })
</form>
應用程序在彈出窗口中執行數據操作。它使用Bootstrap模型彈出。一旦它在瀏覽器中打開,它就會在瀏覽器中保存。要從緩存和加載數據中刪除,我們按照以下代碼片段創建一個javascript文件。
(function ($) {
function Book() {
var $this = this;
function initilizeModel() {
$("#modal-action-book").on('loaded.bs.modal', function (e) {
}).on('hidden.bs.modal', function (e) {
$(this).removeData('bs.modal');
});
}
$this.init = function () {
initilizeModel();
}
}
$(function () {
var self = new Book();
self.init();
})
}(jQuery))
讓我們運行應用程序,點擊列表中的“添加書籍”按鈕或“編輯”按鈕。它稱之為AddEditBook操作方法,它將部分視圖作為響應發送。圖3顯示了添加/編輯圖書的UI。

圖3:編輯圖書視圖UI
刪除視圖
讓我們執行最后的操作刪除。每個圖書數據在清單中都有一個delete按鈕。當用戶點擊“刪除”按鈕時,彈出顯示“你想刪除xxx嗎?”作為一個確認。這個刪除彈出框有兩個按鈕一個是刪除,另一個是取消。當用戶單擊彈出的刪除按鈕時,它會發出一個HttpPost請求,調用DeleteBook操作方法並刪除書。下面是_DeleteBook.cshtml的代碼片段
@model String
@using FirstCRUDApplication.Models
@using (Html.BeginForm())
{
@Html.Partial("_ModalHeader", new ModalHeader { Heading = "Delete Book" })
<div class="modal-body form-horizontal">
Are you want to delete @Model?
</div>
@Html.Partial("_ModalFooter", new ModalFooter { SubmitButtonText="Delete"})
}
讓我們運行應用程序並單擊清單的Delete按鈕。它顯示模型中的UI,如圖4中刪除一本書。

圖4:確認刪除一本書
結論
本文使用ASP.NET Core和Entity Framework Core與code first開發應用程序並在模型彈出窗口中執行數據CRUD操作。這個演示的完整源代碼可以在GitHub上下載,點擊這里下載。
歡迎轉載,轉載請注明翻譯原文出處(本文章),原文出處(原博客地址),然后謝謝觀看
如果覺得我的翻譯對您有幫助,請點擊推薦支持:)
