Entity Framework Core系列之实战(ASP.NET Core MVC应用程序)
本示例演示在ASP.NET 应用程序中使用EF CORE创建数据库并对其做基本的增删改查操作。当然我们默认你的机器上已经安装了.NET CORE SDK以及合适的IDE.本例使用的是Visual Studio Code.
创建一个ASP.NET Core 应用程序
如果你电脑上安装了VS2015或者更高版本,就可以使用项目模板创建一个ASP.NET Core application,或者可以使用命令行工具创建项目。在本例中我们将在Visual Studio Code 中使用命令行工具:
第一步:创建一个文件夹,哪个盘都行,假设我们创建y一个叫做EFCoreWebDemo的文件夹,创建之后用Visual Studio Code 打开,再打开终端窗口:

在终端窗口下执行以下命令:
> dotnet new mvc 创建一个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)
> dotnet restore 恢复项目的依赖项
> dotnet run编译和运行
应用程序应该在端口5000(5001)上运行
https://localhost:5001/

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

继续下一步,按Ctrl+C停止运行应用程序
输入以下命令看ef命令是否可用,出现如下界面,说明是可用的,ef core安装成功。

创建Model
新建一个Model文件夹到项目中,然后在Model文件夹中新建一个EFCoreMvcDemoContext.cs类文件,并给文件中添加如下代码
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()]
public string Title { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
}
public class Author
{
public int AuthorId { get; set; }
[StringLength()]
public string FirstName { get; set; }
[StringLength()]
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
另外欢迎关注我的微信公众号:

Entity Framework Core系列之实战(ASP.NET Core MVC应用程序)的更多相关文章
- ASP.NET Core 系列[1]:ASP.NET Core 初识
ASP.NET Core 是一个跨平台的高性能开源框架,是一个用于连接到互联网的基于云的现代应用程序. ASP.NET Core 用于构建如 Web 应用.物联网(IoT)应用和移动后端应用,这些应用 ...
- .net core系列之初识asp.net core
.net core已经发布了2.0版本,相对于1.0的有了很大的完善,最近准备在项目中尝试使用asp.net core,所以就进行了一些简单的研究. 初识asp.net core分为以下几个部分: 1 ...
- 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)
前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...
- 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)(转)
前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...
- 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)
前言 Entity Framework 延伸系列目录 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这 ...
- Entity Framework入门系列(1)-扯淡开篇
这是我在Cnblogs上的第一个系列,但愿能坚持下去: 惯例索引 Entity Framework入门系列(1)-开篇兼索引: Entity Framework入门系列(2)-初试Code First ...
- Entity Framework Plus 系列目录
Entity Framework Plus 系列文章计划的已经全部写完,可能还有其他功能没有写到,希望大家能够多动手,尝试一下使用,一定会给您带来一些帮助的.文章全部写完,也应该出一个目录方便查看,目 ...
- 【转】Entity Framework技术系列之7:LINQ to Entities
前言 LINQ(Language Integrated Query,语言集成查询)是一组用于C#和VB.NET语言的扩展,它允许编写C#或者VB.NET代码,以与查询数据库相同的方式操作内存数据. L ...
- Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一)【转载】
Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一) 自从搞好了单向一对一关系,装满代码的心中塞进了挥之不去的情丝 —— 单相思.谁都知道音乐世界离不开情感,可谁又知 ...
- Entity Framework技巧系列之六 - Tip 20 – 25
提示20. 怎样处理固定长度的主键 这是正在进行中的Entity Framework提示系列的第20篇. 固定长度字段填充: 如果你的数据库中有一个固定长度的列,例如像NCHAR(10)类型的列,当你 ...
随机推荐
- 利用Sklearn实现加州房产价格预测,学习运用机器学习的整个流程(包含很多细节注解)
Chapter1_housing_price_predict .caret, .dropup > .btn > .caret { border-top-color: #000 !impor ...
- 改善 C# 的语言习惯(一) - 使用属性而不是可访问的数据成员(整理中)
改善 C# 的语言习惯(一) - 使用属性而不是可访问的数据成员 序 为什么我们的程序运行得棒棒的,还要改呢?Why? 答:我们要让程序运行得更快,执行的效率更高,代码的可读性更强,维护的成本更低.. ...
- Java基础:Object类中的equals与hashCode方法
前言 这个系列的文章主要用来记录我在学习和复习Java基础知识的过程中遇到的一些有趣好玩的知识点,希望大家也喜欢. 一切皆对象 对于软件工程来说面向对象编程有一套完整的解决方案:OOA.OOD.O ...
- 【Mybatis】使用Mybatis-Generator自动生成entity、dao、mapping
使用过mybatis的应该都有用过Mybatis-Generator,本文主要介绍使用Mybatis-Generator来自动生成entity.dao.mapping文件. Mybatis-Gener ...
- MySql 双主多从配置指导
MySql 双主多从配置指导 一.背景 互联网项目为了数据的可靠性和架构的可拓展性经常会用到双主多从的数据库,来实现数据的备份.负载均衡和突发状况时数据库切换. 二.思路 配置两台数据库A.B互为主从 ...
- 讲讲跳跃表(Skip Lists)
跳跃表(Skip Lists)是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树相媲美,并且在实现上比平衡树要更为 ...
- Web前端 页面功能——点击按钮返回顶部的实现方法
1. 最简单的静态返回顶部,点击直接跳转页面顶部,常见于固定放置在页面底部返回顶部功能 方法一:用命名锚点击返回到顶部预设的id为top的元素 html代码 <a href="#top ...
- js中slice,SubString和SubStr的区别
来自:https://blog.csdn.net/qq_37120738/article/details/79086706 侵删 slice() 定义和用法 slice() 方法可从已有的数组中返回选 ...
- pip 使用豆瓣源
pip 使用豆瓣源 由于pip 默认使用Python的官方源pypi.python.org/pypi,导致我们经常使用pip装包时速度过慢或者无法安装(请求超时)等问题, 所以国内用户建议使用pip ...
- 小程序实践(十一):showModal的使用
显示模态对话框,确定和取消两个选择+标题+内容的对话框 . // 编辑用户性别 tapSex:function(res){ var that = this wx.showModal({ title: ...
