Entity Framework Core系列之实战(ASP.NET Core MVC应用程序)

本示例演示在ASP.NET 应用程序中使用EF CORE建立数据库并对其作基本的增删改查操做。固然咱们默认你的机器上已经安装了.NET CORE SDK以及合适的IDE.本例使用的是Visual Studio Code.html

建立一个ASP.NET Core 应用程序

若是你电脑上安装了VS2015或者更高版本,就可使用项目模板建立一个ASP.NET Core application,或者可使用命令行工具建立项目。在本例中咱们将在Visual Studio Code 中使用命令行工具:数据库

第一步:建立一个文件夹,哪一个盘都行,假设咱们建立y一个叫作EFCoreWebDemo的文件夹,建立以后用Visual Studio Code 打开,再打开终端窗口:浏览器

在终端窗口下执行如下命令:微信

建立一个MVC应用程序> dotnet new mvc

> dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 2.1.0
> dotnet add package Microsoft.EntityFrameworkCore.Tools --version 2.1.0

从Nuget添加一些须要的包到项目中(这里必定要注意版本version一致,,不然会报错,个人本机是2.1.0)mvc

恢复项目的依赖项> dotnet restore
编译和运行
应用程序应该在端口5000(5001)上运行
https://localhost:5001/> dotnet run

若是在首选浏览器中导航到http://localhost:5001,应该会看到标准的Microsoft MVC应用程序正在运行:app

继续下一步,按Ctrl+C中止运行应用程序async

输入如下命令看ef命令是否可用,出现以下界面,说明是可用的,ef core安装成功。ide

建立Model工具

新建一个Model文件夹到项目中,而后在Model文件夹中新建一个EFCoreMvcDemoContext.cs类文件,并给文件中添加以下代码ui

 

using Microsoft.EntityFrameworkCore; namespace EFCoreMvcDemo { public class EFCoreMvcDemoContext : DbContext { public DbSet<Book> Books { get; set; } public DbSet<Author> Authors { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=.\;Database=EFCoreWebDemo;Trusted_Connection=True;MultipleActiveResultSets=true"); } } }

代码解析:

EFCoreMvcDemoContext继承自DbContext。这个类有两个DbSet属性,它们表示数据库中的表(尚未建立)。EFCoreMvcDemoContext类还包括一个名为onconfiguration的方法,用于定义SQL Server数据库的链接字符串,根据实际状况更改为本身的数据库链接便可唠。

添加Author.cs类,并给其加上如下代码

using System.Collections.Generic; namespace EFCoreMvcDemo { public class Author { public int AuthorId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public ICollection<Book> Books { get; set; } = new List<Book>(); } }

 

再添加Book.cs,并给其添加如下代码

namespace EFCoreMvcDemo { public class Book { public int BookId { get; set; } public string Title { get; set; } public int AuthorId { get; set; } public Author Author { get; set; } } }

此时能够执行dotnet build看下应用程序是否有bug。

添加一个迁移

迁移是为了保持数据库模式和实体model同步,由于咱们目前尚未数据库,因此第一次迁移会根据EFCoreMvcDemoContext上的DbSet属性表示的实体建立数据库并添加表。

Visual Studio Code不提供建立或者迁移的支持,因此咱们依然要用命令行的方法去迁移,一样在终端窗口导航到项目文件夹,并执行如下命令:

dotnet ef  migrations add CreateDatabase

执行完以后,项目中会多一个名为Migrations的文件夹,它包含迁移的代码和模型快照。

执行如下命令执行迁移代码

dotnet ef database update

刷新如下数据库,能够看到名为EFCoreWebDemo数据库建立完成,可是咱们也能够看到表中的全部字段都是nvarchar(max)

使用迁移修改数据库

在下一节中,您将修改模型以设置所选字符串属性大小的限制,而后使用迁移将这些更改更新到数据库。

在Book.cs和Author.cs中增长以下引用:

using System.ComponentModel.DataAnnotations;

修改Book.cs和Author.cs成以下

public class Book { public int BookId { get; set; } [StringLength(255)] public string Title { get; set; } public int AuthorId { get; set; } public Author Author { get; set; } }
public class Author { public int AuthorId { get; set; } [StringLength(50)] public string FirstName { get; set; } [StringLength(75)] public string LastName { get; set; } public ICollection<Book> Books { get; set; } = new List<Book>(); }

最后执行如下命令

dotnet ef migrations add LimitStrings
dotnet ef database update

 这将会改变Books表中的Title字段大小,Authors表中的FirstName和LastName大小,咱们以Author表为例,看下数据库中的变化:

 

 实践操做(新增和显示)

新建一个Web页面,用于显示和添加Author,在Controllers文件夹中新加一个AuthorController.cs文件,代码以下:

using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace EFCoreMvcDemo.Controllers { public class HomeController : Controller { //从数据库中检索全部的Authors,并传递给view
        public async Task<IActionResult> Index() { using (var context = new EFCoreMvcDemoContext()) { var model = await context.Authors.AsNoTracking().ToListAsync(); return View(model); } } [HttpGet] public IActionResult Create() { return View(); } //添加一个Author到数据库
 [HttpPost] public async Task<IActionResult> Create([Bind("FirstName, LastName")] Author author) { using (var context = new EFCoreMvcDemoContext()) { context.Add(author); await context.SaveChangesAsync(); return RedirectToAction("Index"); } } } }

 

AsNoTracking方法是为了在查询的过程当中防止Context没必要要的追踪,使得查询效率更快,由于它用于只读的状况。DbContext放在using模块中实例化,确保其正确的执行。
而后在Views文件夹下添加一个名为Author的文件夹,在Author文件夹下添加Index.cshtml,代码以下:
@model IEnumerable<Author> @{ ViewBag.Title = "Authors"; } <h1>@ViewBag.Title</h1>
<ul> @foreach (var author in Model) { <li>@author.FirstName @author.LastName</li> } </ul>

<div>@Html.ActionLink("New", "create")
再添加Create.cshtml,代码以下:
@model Author @{ ViewBag.Title = "New Author"; } <h1>@ViewBag.Title</h1> @using(Html.BeginForm()){ <div class="form-group"> @Html.LabelFor(model => model.FirstName) @Html.TextBoxFor(model => model.FirstName, new { @class="form-control"}) </div>
  <div class="form-group"> @Html.LabelFor(model => model.LastName) @Html.TextBoxFor(model => model.LastName, new { @class="form-control"}) </div>
  <button type="submit" class="btn btn-default">Submit</button> }

执行命令dotnet run运行,浏览器打开链接http://localhost:5001/author/create,会看到一个新增页面以下:

 

输入新增Author的FirstName和LastName,提交表格,页面会跳转到Index页面,Index会显示数据库中全部Author列表:


添加相关数据(多个实体)
在下一示例中,将会添加与已存在的做者相关联的书籍
首先在Controllers文件夹下添加BookController.cs文件,代码以下:
using System.Threading.Tasks; using System.Linq; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc.Rendering; namespace EFCoreMvcDemo.Controllers { public class BookController : Controller { //检索全部的做者并使用Include方法从数据库中相关联的Books也加载出来,返回给View
        public async Task<IActionResult> Index() { using (var context = new EFCoreMvcDemoContext()) { var model = await context.Authors.Include(a => a.Books).AsNoTracking().ToListAsync(); return View(model); } } [HttpGet] public async Task<IActionResult> Create() { using(var context = new EFCoreMvcDemoContext()) { var authors = await context.Authors.Select(a => new SelectListItem { Value = a.AuthorId.ToString(), Text = $"{a.FirstName} {a.LastName}" }).ToListAsync(); ViewBag.Authors = authors; } return View(); } [HttpPost] public async Task<IActionResult> Create([Bind("Title, AuthorId")] Book book) { using (var context = new EFCoreMvcDemoContext()) { context.Books.Add(book); await context.SaveChangesAsync(); return RedirectToAction("Index"); } } } }

上段代码再次使用了 AsNoTracking方法,也就是说检索出来的Authors和Books只是用来显示,不能被修改。

Index方法:检索全部的做者并使用Include方法从数据库中相关联的Books也加载出来,返回给View。

第一个Create方法:从数据库中检索每一个做者并将其投影到一个新表单——SelectListItem。非实体类型不受上下文跟踪,这就是为何在本例中不使用AsNoTracking方法的缘由,尽管数据是只读的。

第二个Create方法:第二个建立方法的特征是将实体添加到它的DbSet中,而不是像做者那样使用DbContext。

在Views文件夹下添加Book文件夹,在Book文件夹下添加文件 Index.cshtml,将如下代码复制过去:

@model IEnumerable<Author> @{ ViewBag.Title = "Authors and their books"; } <h1>@ViewBag.Title</h1> @if(Model.Any()){ <ul> @foreach(var author in Model){ <li>@author.FirstName @author.LastName <ul> @foreach(var book in author.Books){ <li>@book.Title</li> } </ul>
        </li> } </ul> } <div>@Html.ActionLink("New", "create")

 

再在Book文件夹下添加Create.cshtml 文件,复制代码以下:

@model Book @{ ViewBag.Title = "New Book"; } <h1>@ViewBag.Title</h1> @using(Html.BeginForm()){ <div class="form-group"> @Html.LabelFor(model => model.AuthorId) @Html.DropDownListFor(model => model.AuthorId, (IEnumerable<SelectListItem>)ViewBag.Authors, string.Empty, new { @class="form-control"}) </div>
  <div class="form-group"> @Html.LabelFor(model => model.Title) @Html.TextBoxFor(model => model.Title, new { @class="form-control"}) </div>
  <button type="submit" class="btn btn-default">Submit</button> }

执行命令dotnet run运行,浏览器打开链接http://localhost:5001/book/create,会看到一个新增Book页面以下:

AuthorId下拉列表是全部数据库中的做者,选择一个AuthorId,输入Title,提交页面,以后会跳转到Index页面,index页面会显示全部的Authors和Books:

很easy的就完成了列表展现和新增功能哦。

原文连接:https://www.learnentityframeworkcore.com/walkthroughs/aspnetcore-application

另外欢迎关注个人微信公众号:

相关文章
相关标签/搜索