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(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 LimitStringsdotnet 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

原文地址:https://www.cnblogs.com/yixuanhan/p/9283389.html

时间: 2024-10-12 22:30:11

Entity Framework Core系列之实战(ASP.NET Core MVC应用程序)的相关文章

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

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC MiniProfiler是Stack Overf

Entity Framework技术系列之8:使用Entity Framework技术实现RBAC模型

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 前言 RBAC(Role-Based Access Control,基于角色的访问控制),是继DAC(Discretionary Access Control,自主访问控制)和MAC(Mandatory Access Control,强制访问控

实战Asp.Net Core:部署应用

原文:实战Asp.Net Core:部署应用 1.前言 某一刻,你已经把 .Net Core 的程序写好了.接下来,还可以做什么呢?那就是部署了. 作为一名开发工程师,如果不会部署自己开发的应用,那么这也是不完整的.接下来,我们就来说说,如何部署我们的 .Net Core 应用程序(主要是 Asp.Net Core 应用). 2.Asp.Net Core 的部署方式 对于虚拟机中执行的语言来说,大都会有 SDK(Software Development Kit) 以及 XRE(X Runtime

Entity Framework Plus 系列目录

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

Entity Framework技术系列之7:LINQ to Entities

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 前言 LINQ(Language Integrated Query,语言集成查询)是一组用于C#和VB.NET语言的扩展,它允许编写C#或者VB.NET代码,以与查询数据库相同的方式操作内存数据.LINQ提Entity Framework技术系

Entity Framework技巧系列之五 - Tip 16 – 19

提示16. 当前如何模拟.NET 4.0的ObjectSet<T> 背景: 当前要成为一名EF的高级用户,你确实需要熟悉EntitySet.例如,你需要理解EntitySet以便使用 AttachTo(-) 或创建EntityKey. 在大部分情况下,针对每个对象/clr类型只有一个可能的EntitySet.Tip 13正是利用这种想法来简化附加(Attach)对象并且你也可以对Add使用类似的技巧. 然而为了在.NET 4.0中解决这个问题,我们添加了一个叫做 ObjectSet<T&

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

前言 Entity Framework 延伸系列目录 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这是一个对Entity Framework进行扩展的类库. 完全支持EF 5.0/6.0+, GitHub地址 https://github.com/loresoft/EntityFramework.Extended, 最后一次更新是在2015/07/10 这个库支持批量更新,删除.查询结果缓存和审计

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

提示20. 怎样处理固定长度的主键 这是正在进行中的Entity Framework提示系列的第20篇. 固定长度字段填充: 如果你的数据库中有一个固定长度的列,例如像NCHAR(10)类型的列,当你进行一次插入时,填充会自动发生.所以例如如果你插入'12345',你将得到5个自动填充的空格,来创建一个10个字符长度的字符串. 大多数情况下,这种自动填充不会有问题.但是在使用Entity Framework时如果你使用这些列的一个作为你的主键,你可能会在进行标识识别(identity resol

[转]Creating an Entity Framework Data Model for an ASP.NET MVC Application (1 of 10)

本文转自:http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application Creating an Entity Framework Data Model for an ASP.NET MVC Application (1 of 10) By      

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

前言 LINQ(Language Integrated Query,语言集成查询)是一组用于C#和VB.NET语言的扩展,它允许编写C#或者VB.NET代码,以与查询数据库相同的方式操作内存数据. LINQ提Entity Framework技术系列之7:LINQ to Entities供了丰富的类似SQL的查询语法,功能强大且容易上手.下图汇总展示了LINQ技术的官方实现集合: 图1官方LINQ实现汇总图 正 如上图所示,LINQ to Entities 是LINQ技术在实体对象模型中的一种实现