本示例演示在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应用程序)的更多相关文章

  1. ASP.NET Core 系列[1]:ASP.NET Core 初识

    ASP.NET Core 是一个跨平台的高性能开源框架,是一个用于连接到互联网的基于云的现代应用程序. ASP.NET Core 用于构建如 Web 应用.物联网(IoT)应用和移动后端应用,这些应用 ...

  2. .net core系列之初识asp.net core

    .net core已经发布了2.0版本,相对于1.0的有了很大的完善,最近准备在项目中尝试使用asp.net core,所以就进行了一些简单的研究. 初识asp.net core分为以下几个部分: 1 ...

  3. 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)

    前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...

  4. 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)(转)

    前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...

  5. 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)

    前言 Entity Framework 延伸系列目录 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这 ...

  6. Entity Framework入门系列(1)-扯淡开篇

    这是我在Cnblogs上的第一个系列,但愿能坚持下去: 惯例索引 Entity Framework入门系列(1)-开篇兼索引: Entity Framework入门系列(2)-初试Code First ...

  7. Entity Framework Plus 系列目录

    Entity Framework Plus 系列文章计划的已经全部写完,可能还有其他功能没有写到,希望大家能够多动手,尝试一下使用,一定会给您带来一些帮助的.文章全部写完,也应该出一个目录方便查看,目 ...

  8. 【转】Entity Framework技术系列之7:LINQ to Entities

    前言 LINQ(Language Integrated Query,语言集成查询)是一组用于C#和VB.NET语言的扩展,它允许编写C#或者VB.NET代码,以与查询数据库相同的方式操作内存数据. L ...

  9. Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一)【转载】

    Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一) 自从搞好了单向一对一关系,装满代码的心中塞进了挥之不去的情丝 —— 单相思.谁都知道音乐世界离不开情感,可谁又知 ...

  10. Entity Framework技巧系列之六 - Tip 20 – 25

    提示20. 怎样处理固定长度的主键 这是正在进行中的Entity Framework提示系列的第20篇. 固定长度字段填充: 如果你的数据库中有一个固定长度的列,例如像NCHAR(10)类型的列,当你 ...

随机推荐

  1. [VsCode] 开发所使用的VsCode的插件

    vscode 的插件 必须 Chinese (Simplified) Language Pack for Visual Studio Code Markdown Preview Enhanced De ...

  2. Redux进阶(Immutable.js)

    更好的阅读体验 更好的阅度体验 Immutable.js Immutable的优势 1. 保证不可变(每次通过Immutable.js操作的对象都会返回一个新的对象) 2. 丰富的API 3. 性能好 ...

  3. Java开发笔记(四)Java帝国的度量衡

    秦始皇统一中国之后,实行“书同文,车同轨”,把货币和各种度量衡都统一起来,从而缔造了一个秩序井然的帝国.既然统一度量衡是每个帝国都要做的事情,Java帝国也不例外,对于人生地不熟的初学者来说,只有认识 ...

  4. JVM 调优参数解释

    典型配置: java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseP ...

  5. SpringDay01

    Spring的控制反转 Spring的依赖注入 多种注入方式 多种属性的注入方式 <bean id="userDao" class="dao.UserDaoImpl ...

  6. installation failed with message INSTALL_FAILED_INSUFFICIENT_STORG

    在安装APK的时候有时候会出现这种错误,原因是卸载之前的APK不彻底,有残余,手动删除android目录下相关的文件.

  7. Android 网络框架 Retrofit2

    概述 Retrofit是一个OkHttp网络请求框架的封装库,Retrofit通过注解配置网络参数,可以按照我们的规则去构造实际的HTTP请求,能够灵活设置URL.头部.请求体.返回值等,是目前最优雅 ...

  8. Node的简介

    从开始学习node到现在已经有半年多了,中间没有做过什么实际工作中的项目,所以感觉自己的知识有些匮乏,但是我还是要写这些文章,因为工作中的需要用node来开发后台环境,再加上我对这些知识记得不多,都是 ...

  9. ADOConnection断线重连

    问题: ADOConnection断线重连问题描述: 使用ADOConnection连接oracle数据库,开始正常,当网络断开时数据库连接失败(此时查询ADOConnection.connected ...

  10. Python XML解析之DOM

    DOM说明: DOM:Document Object Model API DOM是一种跨语言的XML解析机制,DOM把整个XML文件或字符串在内存中解析为树型结构方便访问. https://docs. ...