ASP.NET Core Razor Pages 使用 EntityFramework Core 和枚举字符串 - 第二部分





5.00/5 (4投票s)
完成初始 CRUD 页面
引言
这是多部分文章的第二部分,演示了如何通过 EntityFramework Core 2.1 (EF) 将 C# enum
值映射到数据库表中的 string
值。它在 ASP.NET Core Razor Page 应用程序的上下文中,解决了 enum
值与应用程序实体之间的一对多和多对多关系映射问题。
EF 是一个对象关系映射器 (ORM)。在这样的应用程序中,存在两个“世界”。一个是以 C# 对象模型形式存在的对象世界。另一个是存在于关系数据库(如 Microsoft SQL Server)中的关系世界。这两个世界并不一致。ORM(如 EntityFramework
)的功能是连接这两个世界,并促进它们之间的数据传输。
第一部分:我们创建了初始对象模型、Entity Framework 数据上下文和数据库,并显示了第一个 Customers Razor Page。这是所有已定义 Customers 的 Customer 的读取功能 (CRUD)。
在第二部分中,我们将完成并测试 Customer CRUD Razor Pages。
- 实现并测试 Customer 创建 Razor Page,Customers\Create.cshtml。这是
Customer
CRUD 的Create
功能。 - 在 Customers\Details.cshtml Razor Page 中,实现
Customer
详情的显示,这是通过其CustomerId
属性标识的单个Customer
的Read
功能的实现。 - 在 Customers\Edit.cshtml Razor Page 中,实现
Customer
属性的编辑,这是Customer
CRUD 的Update
功能。 - 最后,在 Customers\Delete.cshtml Razor Page 中实现
Customer
CRUD 的Delete
功能。
在第三部分,我们将 创建 Project 和 ProjectState 实体,并实现 ProjectState 和 Projects 之间的一对多关系。
在第四部分,我们将 添加 Skill 实体 (Skill enum, SkillTitle 和 ProjectSkill),并实现 Projects 和 Skills 之间的多对多关系。
Using the Code
完成 Customers CRUD
此时,我们已经完成了对 Customers
表的基本读取。现在,我们将完成剩余的 Customer
CRUD 功能。
Customer 创建
Pages\Customers\Create 文件处理在数据库中创建 Customer
记录。
生成的 Pages\Customers\Create.cshtml
@page
@model QuantumWeb.Pages.Customers.CreateModel
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<h4>Customer</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Customer.CustomerName" class="control-label"></label>
<input asp-for="Customer.CustomerName" class="form-control" />
<span asp-validation-for="Customer.CustomerName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Customer.CustomerContact" class="control-label"></label>
<input asp-for="Customer.CustomerContact" class="form-control" />
<span asp-validation-for="Customer.CustomerContact" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Customer.CustomerPhone" class="control-label"></label>
<input asp-for="Customer.CustomerPhone" class="form-control" />
<span asp-validation-for="Customer.CustomerPhone" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Customer.CustomerEmail" class="control-label"></label>
<input asp-for="Customer.CustomerEmail" class="form-control" />
<span asp-validation-for="Customer.CustomerEmail" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
此文件包含一个 <form>
元素,用于将用户输入 POST
到服务器。
修改后的 Pages\Customers\Create.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using QuantumWeb.Data;
using QuantumWeb.Model;
namespace QuantumWeb.Pages.Customers
{
public class CreateModel : PageModel
{
private readonly QuantumDbContext _context;
public CreateModel(QuantumDbContext context)
{
_context = context;
} // end public CreateModel(QuantumDbContext context)
public IActionResult OnGet()
{
return Page();
} // end public IActionResult OnGet()
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customer.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
} // end public async Task<IActionResult> OnPostAsync()
} // end public class CreateModel : PageModel
} // end namespace QuantumWeb.Pages.Customers
可以通过点击 Customers
页上的“Create New”链接来访问 Customers
/Create
页面。
QuantumWeb 应用程序 Customers 页面:https//: 44306/Customers
在 **Customer Create** 页面输入第一个 Customer
的数据,然后点击“Create”。
QuantumWeb 应用程序 Customers 页面:https//: 44306/Customers/Create
QuantumWeb 应用程序 Customers 页面:https//: 44306/Customers (包含第 1 个 Customer)
添加另外两个 Customers
后,我们显示 Customer
页面。
QuantumWeb 应用程序 Customers 页面:https//: 44306/Customers - 3 个 Customers
通过点击 customer
"Polyolefin Processing, Inc." 的“Details”链接,我们可以显示其详情。接下来是 Customers\Details.cshtml 和 Customers\Details.cshtml.cs 文件的列表。
显示 Customer 详情
生成的 Pages\Customers\Details.cshtml
@page
@model QuantumWeb.Pages.Customers.DetailsModel
@{
ViewData["Title"] = "Details";
}
<h2>Details</h2>
<div>
<h4>Customer</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerName)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerName)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerContact)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerContact)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerPhone)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerPhone)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerEmail)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerEmail)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="@Model.Customer.CustomerId">Edit</a> |
<a asp-page="./Index">Back to List</a>
</div>
修改后的 Pages\Customers\Details.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using QuantumWeb.Data;
using QuantumWeb.Model;
namespace QuantumWeb.Pages.Customers
{
public class DetailsModel : PageModel
{
private readonly QuantumDbContext _context;
public DetailsModel(QuantumDbContext context)
{
_context = context;
} // end public DetailsModel(QuantumDbContext context)
public Customer Customer { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
} // end if (id == null)
Customer = await _context.Customer.FirstOrDefaultAsync(m => m.CustomerId == id);
if (Customer == null)
{
return NotFound();
} // endif (Customer == null)
return Page();
} // end public async Task<IActionResult> OnGetAsync(int? id)
} // end public class DetailsModel : PageModel
} // end namespace QuantumWeb.Pages.Customers
QuantumWeb 应用程序 Customer Details 页面:https//: 44306/Customers/Details?id=2
QuantumWeb 应用程序 Customers 页面:https//: 44306/Customers - 3 个 Customers
通过点击 customer
"Pascagoula Petrochemicals" 的“Edit”链接,我们可以编辑该客户的记录。接下来是 Customers\Edit.cshtml 和 Customers\Edit.cshtml.cs 文件的列表。
编辑 Customer 信息
生成的 Pages\Customers\Edit.cshtml
@page
@model QuantumWeb.Pages.Customers.EditModel
@{
ViewData["Title"] = "Edit";
}
<h2>Edit</h2>
<h4>Customer</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Customer.CustomerId" />
<div class="form-group">
<label asp-for="Customer.CustomerName" class="control-label"></label>
<input asp-for="Customer.CustomerName" class="form-control" />
<span asp-validation-for="Customer.CustomerName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Customer.CustomerContact" class="control-label"></label>
<input asp-for="Customer.CustomerContact" class="form-control" />
<span asp-validation-for="Customer.CustomerContact" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Customer.CustomerPhone" class="control-label"></label>
<input asp-for="Customer.CustomerPhone" class="form-control" />
<span asp-validation-for="Customer.CustomerPhone" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Customer.CustomerEmail" class="control-label"></label>
<input asp-for="Customer.CustomerEmail" class="form-control" />
<span asp-validation-for="Customer.CustomerEmail" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
修改后的 Pages\Customers\Edit.cshtml.cs
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using QuantumWeb.Data;
using QuantumWeb.Model;
namespace QuantumWeb.Pages.Customers
{
public class EditModel : PageModel
{
private readonly QuantumDbContext _context;
public EditModel(QuantumDbContext context)
{
_context = context;
} // end public EditModel(QuantumDbContext context)
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
} // endif (id == null)
Customer = await _context.Customer.FirstOrDefaultAsync(m => m.CustomerId == id);
if (Customer == null)
{
return NotFound();
} // endif (Customer == null)
return Page();
} // end public async Task<IActionResult> OnGetAsync(int? id)
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
} // endif (!ModelState.IsValid)
_context.Attach(Customer).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
} // end try
catch (DbUpdateConcurrencyException)
{
if (!CustomerExists(Customer.CustomerId))
{
return NotFound();
}
else
{
throw;
} // endif (!CustomerExists(Customer.CustomerId))
} // end catch (DbUpdateConcurrencyException)
return RedirectToPage("./Index");
} // end public async Task<IActionResult> OnPostAsync()
private bool CustomerExists(int id)
{
return _context.Customer.Any(e => e.CustomerId == id);
} // end private bool CustomerExists(int id)
} // end public class EditModel : PageModel
} // end namespace QuantumWeb.Pages.Customers
QuantumWeb 应用程序 Customer Edit 页面:https//: 44306/Customers/Edit?id=3
我们更改所选 Customer
的值并保存更改。
QuantumWeb 应用程序 Customers 页面:https//: 44306/Customers - 修改后的 Customer
我们看到已编辑的值。现在,通过点击 Customer
的“Delete”链接,我们删除一个 Customer
。接下来是 Customers\Delete.cshtml 和 Customers\Delete.cshtml.cs 文件的列表。
删除 Customer 记录
生成的 Pages\Customers\Delete.cshtml
@page
@model QuantumWeb.Pages.Customers.DeleteModel
@{
ViewData["Title"] = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Customer</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerName)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerName)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerContact)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerContact)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerPhone)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerPhone)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Customer.CustomerEmail)
</dt>
<dd>
@Html.DisplayFor(model => model.Customer.CustomerEmail)
</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="Customer.CustomerId" />
<input type="submit" value="Delete" class="btn btn-default" /> |
<a asp-page="./Index">Back to List</a>
</form>
</div>
修改后的 Pages\Customers\Delete.cshtml.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using QuantumWeb.Data;
using QuantumWeb.Model;
namespace QuantumWeb.Pages.Customers
{
public class DeleteModel : PageModel
{
private readonly QuantumDbContext _context;
public DeleteModel(QuantumDbContext context)
{
_context = context;
} // end public DeleteModel(QuantumDbContext context)
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
} // endif (id == null)
Customer = await _context.Customer.FirstOrDefaultAsync(m => m.CustomerId == id);
if (Customer == null)
{
return NotFound();
} // endif (Customer == null)
return Page();
} // end public async Task<IActionResult> OnGetAsync(int? id)
public async Task<IActionResult> OnPostAsync(int? id)
{
if (id == null)
{
return NotFound();
} // endif (id == null)
Customer = await _context.Customer.FindAsync(id);
if (Customer != null)
{
_context.Customer.Remove(Customer);
await _context.SaveChangesAsync();
} // endif (Customer != null)
return RedirectToPage("./Index");
} // end public async Task<IActionResult> OnPostAsync(int? id)
} // end public class DeleteModel : PageModel
} // end namespace QuantumWeb.Pages.Customers
QuantumWeb 应用程序 Customer Delete 页面:https//: 44306/Customers/Delete?id=3
我们显示客户 "Pascagoula Petrochemicals, Ltd" 的详情,并提供通过点击“Delete”按钮来删除它的选项。
QuantumWeb 应用程序 Customers 页面:https//: 44306/Customers - 2 个 Customers
摘要
我们已经实现了 Customer
CRUD ASP.NET Razor Pages。
关注点
在这篇第三部分的文章中,我们将定义 Project
和 ProjectState
实体 (Project
, ProjectState
和 ProjectStateDescription
),并实现 ProjectState
s 和 Project
s 之间的一对多关系。