使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序
使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序
不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址
本文打算使用Entity Framework Core解释ASP.NET Core MVC中的基本创建,读取,更新和删除(CRUD)操作。我们使用Entity Framework Code First的方法开发应用程序 ,要设置ASP.NET Core MVC应用程序的开发环境,我们遵循本文中开始使用 ASP.NET Core MVC.的步骤。应用程序使用一个名为Book的实体来执行CRUD操作,并做一些简单的演示。
更多精彩内容
创建数据库
这个应用程序采用的是Entity Framework Core 中的Code First(代码优先)方法,所以我们首先要添加Entity Framework Core ,这个应用程序使用的是SQL Server数据库,因此我们需要提供SQL Server数据库程序该,提供程序可通过名为 Microsoft.EntityFrameworkCore.SqlServer的 NuGet软件包提供。当应用程序创建时,它包括Microsoft.AspNetCore.All NuGet元包。此包还包括Microsoft.EntityFrameworkCore.SqlServer,因此我们不必安装它。
创建数据实体模型
应用程序在单个实体上执行CRUD操作,但是现在我们创建了两个实体,这些实体分别是BaseEntity和Book。BaseEntity类具有公共属性,,是其他实体的父类,并将由其他实体继承。BaseEntity类按照下面的代码片段创建。
using System;
namespace FirstCRUDApplication.DbEntities
{
public class BaseEntity
{
public Int64 Id { get; set; }
public DateTime AddedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string IPAddress { get; set; }
}
}
应用程序在名为Book的实体上执行CRUD操作。现在,我们创建一个Book类并继承BaseEntity。
namespace FirstCRUDApplication.DbEntities
{
public class Book:BaseEntity
{
public string Name { get; set; }
public string ISBN { get; set; }
public string Author { get; set; }
public string Publisher { get; set; }
}
}
现在,让我们为Book实体定义配置。数据库表将使用Book实体的配置创建。定义配置有两种选择,一种是数据注释 ,另一种是Fluent API。遵循SRP原则,我们使用第二个选项Fluent API定义实体配置。下面是BookMap类的代码片段
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace FirstCRUDApplication.DbEntities
{
public class BookMap
{
public BookMap(EntityTypeBuilder<Book> entityBuilder)
{
entityBuilder.HasKey(t => t.Id);
entityBuilder.Property(t => t.Name).IsRequired();
entityBuilder.Property(t => t.ISBN).IsRequired();
entityBuilder.Property(t => t.Author).IsRequired();
entityBuilder.Property(t => t.Publisher).IsRequired();
}
}
}
EntityTypeBuilder<T>支持Entity Framework Core的基础结构。T表示被配置的实体。它使用方法定义每个字段的配置。让我们看一下在前面的代码中使用的一些方法。
- **HasKey: **
它设置了构成主键的实体属性。 - Property: 它返回一个可以用来配置实体类型属性的对象。
现在,我们创建了名为CRUDContext的上下文类。它继承自DbContext。它是实体和数据库之间的桥梁。它是一个主要类,它将数据作为对象进行交互。我们在上下文类中重写OnModelCreating方法。当我们使用Fluent API时,它定义了实体如何映射到数据库。下面是名为CRUDContext.cs的上下文类的代码片段。
using Microsoft.EntityFrameworkCore;
namespace FirstCRUDApplication.DbEntities
{
public class CRUDContext:DbContext
{
public CRUDContext(DbContextOptions<CRUDContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
new BookMap(modelBuilder.Entity<Book>());
}
}
}
使用EF连接数据库
我们定义了一个带有上下文的数据模型。现在,我们定义了数据库和上下文之间的连接。我们必须遵循以下步骤,在应用程序中使用上下文。
- 我们定义一个连接字符串,以便将上下文连接到数据库。打开appsetting.json文件,并根据以下代码片段定义连接字符串。
"ConnectionStrings": {
"DefaultConnection": "Data Source=DESKTOP-RG33QHE;Initial Catalog=ApplicationDb;User ID=sa; Password=admin123"
}
它类似于web.config。它存储配置级别设置,如连接字符串、SMTP、域名等。
- 应用程序配置从
Startup类初始化。由于这个应用程序使用了Entity Framework Core,所以我们在使用中添加了两个名称空间。下面的代码片段是相同的。
using FirstCRUDApplication.DbEntities;
using Microsoft.EntityFrameworkCore;
- ASP.NET Core提供了内置的控制反转。在应用程序启动时,上下文注册到IoC。在此之后,使用构造函数依赖注入,上下文注入到MVC控制器中。因此,它在
Startup类中注册为一个服务。下面的代码片段,用于配置上下文注册为服务的ConfigureServices方法。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<CRUDContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
使用EF 迁移初始化数据库
我们使用Entity Framework Core Migration来根据数据模型创建一个数据库。为了执行迁移,我们可以使用软件包管理器控制台(PMS)和命令行界面(CLI)。
Entity Framework Core工具CLI提供了 Microsoft.EntityFrameworkCore.Tool.DotNet 。要安装这个包,我们不能使用install-package命令或包管理器GUI。但是我们可以在应用程序中编辑.csproj文件,并将这个包添加到 DotNetCliToolReference,从而安装这个包,下面的XML代码是相同的。
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>
现在,我们需要遵循从数据模型创建新数据库的步骤。这些都是
- 保存更改并构建项目。
- 打开解决方案文件夹位置。在解决方案浏览器中,右键单击该项目并从上下文菜单中选择打开文件资源管理器。
- 如下图所示在地址栏中写入cmd命令并按Enter键。
要发起迁移,请在命令窗口中输入以下命令。
dotnet ef migrations添加了InitialCreate

图1:Entity Framework Core Migration
现在,我们将迁移应用到数据库。我们在命令窗口中输入以下命令。该命令在其中创建数据库和表。
dotnet ef database 修改
因此,我们在Entity Framework Core中使用code first方法创建了数据库
创建应用程序用户界面
现在,我们为应用程序开发用户界面。首先,我们为应用程序UI创建名为BookViewModel 的视图模型。这个模型与视图紧密地结合在一起。下面的代码片段用于视图模型。
using System.ComponentModel.DataAnnotations;
namespace FirstCRUDApplication.Models
{
public class BookViewModel
{
public long Id { get; set; }
public string Name { get; set; }
[Display(Name = "ISBN No")]
public string ISBN { get; set; }
public string Author { get; set; }
public string Publisher { get; set; }
}
}
现在,在控制器文件夹下创建一个名为 BookController的控制器。该控制器具有执行CRUD操作的操作方法。CRUDContext类实例使用依赖注入注入它的构造函数。下面的代码片段是一样的。
using FirstCRUDApplication.DbEntities;
using FirstCRUDApplication.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace FirstCRUDApplication.Controllers
{
public class BookController : Controller
{
private CRUDContext context;
public BookController(CRUDContext context)
{
this.context = context;
}
[HttpGet]
public IActionResult Index()
{
IEnumerable<BookViewModel> model = context.Set<Book>().ToList().Select(b => new BookViewModel
{
Id= b.Id,
Name = b.Name,
ISBN = b.ISBN,
Author = b.Author,
Publisher = b.Publisher
});
return View("Index", model);
}
[HttpGet]
public IActionResult AddEditBook(long? id)
{
BookViewModel model = new BookViewModel();
if (id.HasValue)
{
Book book = context.Set<Book>().SingleOrDefault(c => c.Id == id.Value);
if (book != null)
{
model.Id = book.Id;
model.Name = book.Name;
model.ISBN = book.ISBN;
model.Author = book.Author;
model.Publisher = book.Publisher;
}
}
return PartialView("~/Views/Book/_AddEditBook.cshtml", model);
}
[HttpPost]
public IActionResult AddEditBook(long? id, BookViewModel model)
{
try
{
if (ModelState.IsValid)
{
bool isNew = !id.HasValue;
Book book = isNew ? new Book
{
AddedDate = DateTime.UtcNow
} : context.Set<Book>().SingleOrDefault(s => s.Id == id.Value);
book.Name = model.Name;
book.ISBN = model.ISBN;
book.Author = model.Author;
book.Publisher = model.Publisher;
book.IPAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString();
book.ModifiedDate = DateTime.UtcNow;
if (isNew)
{
context.Add(book);
}
context.SaveChanges();
}
}
catch (Exception ex)
{
throw ex;
}
return RedirectToAction("Index");
}
[HttpGet]
public IActionResult DeleteBook(long id)
{
Book book = context.Set<Book>().SingleOrDefault(c => c.Id == id);
string bookName = book.Name;
return PartialView("~/Views/Book/_DeleteBook.cshtml", model: bookName);
}
[HttpPost]
public IActionResult DeleteBook(long id, IFormCollection form)
{
Book book = context.Set<Book>().SingleOrDefault(c => c.Id == id);
context.Entry(book).State = Microsoft.EntityFrameworkCore.EntityState.Deleted;
context.SaveChanges();
return RedirectToAction("Index");
}
}
}
现在,我们为每个CRUD操作开发用户界面。视图为添加和编辑图书、图书列表和删除图书而创建。我们来一个个的来看视图。
图书清单
这是应用程序的第一个视图。它显示了清单中的所有书籍。它以表格格式显示图书数据,并有一个添加新书的选项。图书列表有编辑和删除图书的选项。它是一个名为index的索引视图.cshtml在图书文件夹的视图。下面的代码片段是一样的。
@model IEnumerable<FirstCRUDApplication.Models.BookViewModel>
@using FirstCRUDApplication.Models
@using FirstCRUDApplication.Code
<div class="top-buffer"></div>
<div class="panel panel-primary">
<div class="panel-heading panel-head">Books</div>
<div class="panel-body">
<div class="btn-group">
<a id="createEditBookModal" data-toggle="modal" asp-action="AddEditBook" data-target="#modal-action-book" class="btn btn-primary">
<i class="glyphicon glyphicon-plus"></i> Add Book
</a>
</div>
<div class="top-buffer"></div>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>ISBN</th>
<th>Author</th>
<th>Publisher</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.Name)</td>
<td>@Html.DisplayFor(modelItem => item.ISBN)</td>
<td>@Html.DisplayFor(modelItem => item.Author)</td>
<td>@Html.DisplayFor(modelItem => item.Publisher)</td>
<td>
<a id="editBookModal" data-toggle="modal" asp-action="AddEditBook" asp-route-id= "@item.Id" data-target="#modal-action-book"
class="btn btn-info">
<i class="glyphicon glyphicon-pencil"></i> Edit
</a>
<a id="deleteBookModal" data-toggle="modal" asp-action="DeleteBook" asp-route-id= "@item.Id" data-target="#modal-action-book" class="btn btn-danger">
<i class="glyphicon glyphicon-trash"></i> Delete
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
@Html.Partial("_Modal", new BootstrapModel { ID = "modal-action-book", AreaLabeledId = "modal-action-book-label", Size = ModalSize.Medium })
@section scripts
{
<script src="~/js/book-index.js" asp-append-version="true"></script>
}
现在,让我们运行应用程序。作为第一个请求,它使用HttpGet请求调用index()的action方法,并将UI中列出的所有图书作为响应,如图2所示。

图2:书清单界面
创建/编辑图书视图
由于创建和编辑视图都是相同的,因此我们为这两个视图创建了一个公共视图。这个视图使用相同的BookViewModel。让我们定义一个创建/编辑的图书部分视图。下面是_AddEditBook.cshtml的代码片段。
@model FirstCRUDApplication.Models.BookViewModel
@using FirstCRUDApplication.Models
<form asp-action="AddEditBook" role="form">
@await Html.PartialAsync("_ModalHeader", new ModalHeader { Heading = String.Format("{0} Book", @Model.Id == 0 ? "Add" : "Edit") })
<div class="modal-body form-horizontal">
<div class="form-group">
<label asp-for="Name" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="Name" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="ISBN" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="ISBN" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Author" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="Author" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Publisher" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="Publisher" class="form-control" />
</div>
</div>
</div>
@await Html.PartialAsync("_ModalFooter", new ModalFooter { })
</form>
应用程序在弹出窗口中执行数据操作。它使用Bootstrap模型弹出。一旦它在浏览器中打开,它就会在浏览器中保存。要从缓存和加载数据中删除,我们按照以下代码片段创建一个javascript文件。
(function ($) {
function Book() {
var $this = this;
function initilizeModel() {
$("#modal-action-book").on('loaded.bs.modal', function (e) {
}).on('hidden.bs.modal', function (e) {
$(this).removeData('bs.modal');
});
}
$this.init = function () {
initilizeModel();
}
}
$(function () {
var self = new Book();
self.init();
})
}(jQuery))
让我们运行应用程序,点击列表中的“添加书籍”按钮或“编辑”按钮。它称之为AddEditBook操作方法,它将部分视图作为响应发送。图3显示了添加/编辑图书的UI。

图3:编辑图书视图UI
删除视图
让我们执行最后的操作删除。每个图书数据在清单中都有一个delete按钮。当用户点击“删除”按钮时,弹出显示“你想删除xxx吗?”作为一个确认。这个删除弹出框有两个按钮一个是删除,另一个是取消。当用户单击弹出的删除按钮时,它会发出一个HttpPost请求,调用DeleteBook操作方法并删除书。下面是_DeleteBook.cshtml的代码片段
@model String
@using FirstCRUDApplication.Models
@using (Html.BeginForm())
{
@Html.Partial("_ModalHeader", new ModalHeader { Heading = "Delete Book" })
<div class="modal-body form-horizontal">
Are you want to delete @Model?
</div>
@Html.Partial("_ModalFooter", new ModalFooter { SubmitButtonText="Delete"})
}
让我们运行应用程序并单击清单的Delete按钮。它显示模型中的UI,如图4中删除一本书。

图4:确认删除一本书
结论
本文使用ASP.NET Core和Entity Framework Core与code first开发应用程序并在模型弹出窗口中执行数据CRUD操作。这个演示的完整源代码可以在GitHub上下载,点击这里下载。
欢迎转载,转载请注明翻译原文出处(本文章),原文出处(原博客地址),然后谢谢观看
如果觉得我的翻译对您有帮助,请点击推荐支持:)
使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序的更多相关文章
- Working with Data » 使用Visual Studio开发ASP.NET Core MVC and Entity Framework Core初学者教程
原文地址:https://docs.asp.net/en/latest/data/ef-mvc/intro.html The Contoso University sample web applica ...
- EF(Entity Framework)通用DBHelper通用类,增删改查以及列表
其中 通用类名:DBhelper 实体类:UserInfo 1 //新增 2 DBHelper<UserInfo> dbhelper = new DBHelper<UserInfo& ...
- ASP.NET MVC+EasyUI+Entity FrameWork 整合开发
本文详细讲解怎么用ASP.NET MVC+EasyUI+Entity FrameWork 来开发一个项目 对于ASP.NET MVC的Jscript库,主要引用 <script type=.mi ...
- 手把手教你ASP.NET Core:使用Entity Framework Core进行增删改查
新建表Todo,如图 添加模型类 在"解决方案资源管理器"中,右键单击项目. 选择"添加" > "新建文件夹". 将文件夹命名为 Mo ...
- Mvc5+Entity Framework6 之二----在MVC中用Entity Framework实现基本的CRUD
目标:创建控制器和视图的代码,实现CRUD(创建,读取,更新,删除)功能 创建一个详细信息页 控制器为Students的Index页生成的代码排除Enrollments属性在外,因为该属性中关联着一个 ...
- abp(net core)+easyui+efcore实现仓储管理系统——展现层实现增删改查之列表视图(七)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...
- 基于Entity Framework的自定义分页,增删改的通用实现
简介 之前写个一个基于Dapper的分页实现,现在再来写一个基于Entity Framework的分页实现,以及增删改的通用实现. 代码 还是先上代码:https://github.com/jinwe ...
- MVC模式:实现数据库中数据的增删改查功能
*.数据库连接池c3p0,连接mysql数据库: *.Jquery使用,删除时跳出框,确定是否要删除: *.使用EL和JSTL,简化在jsp页面中插入的java语言 1.连接数据库 (1)导入连接数据 ...
- Entity Framework 学习系列(4) - EF 增删改
目录 写在前面 一.开发环境 二.创建项目 三.新增 1.单表新增 2.批量新增 3.多表新增 四.编辑 1.先查询,后编辑 2.创建实体,后编辑 五.删除 写在前面 在上一小节中,学习了如何 通过C ...
随机推荐
- Linux系统运维工程该具备哪些素质
记得在上高中时,物理老师总是会对我们一句话:"学习是件苦差事."工作后发现,其实做运维也是件苦差事.最为一名运维工程师,深知这一行的艰辛,但和IT行业其他职务一样,那就是付出的越多 ...
- Python中的可变对象和不可变对象
Python中的可变对象和不可变对象 什么是可变/不可变对象 不可变对象,该对象所指向的内存中的值不能被改变.当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一 ...
- [补档][Hnoi2013]游走
[Hnoi2013]游走 题目 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一 ...
- PIVOT行转列
PIVOT通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合. 测试数据 INSERT INTO [TestRows2Columns] ...
- Mysql中让两个字段不同时相同的方法
有时候我们会遇到这样的一种情况:有一些不同的专业,每个专业中有一些不同的学号,专业+学号能对应到个人.这时,应该如何在数据库中定义列,来保证专业+学号对应的学生的唯一性呢? 把学号定义成唯一(UNIQ ...
- 怎么用snapman一个人在三天内开发出一个复杂的软件开发项目管理系统
snapman是一个简单而强大的团队协作软件,在上面的信息可以是数据.可以是规则.也可以是自动化代码:最重要的它是一个可以开发的协作平台,所有信息都可以作用到所有人或机器上,大大减少了工作的复杂度.软 ...
- oracle函数和存储过程有什么区别
oracle函数和存储过程有什么区别 1. 返回值的区别,函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有 2.调用的区别,函数可以在查询语句中直接调用,而存储过程必须单独调用. 函数 ...
- BaseAction 使用
public class AreaAction extends BaseAction<Area> { @Autowired private AreaService areaService; ...
- sql server 2000登录名与数据库用户名的关联问题
MS SQL Server 2000 数据库使用备份还原造成的孤立用户和对象名‘xxx’无效的错误的解决办法 在使用数据库的过程中,经常会遇到数据库迁移或者数据迁移的问题,或者有突然的数据库损 ...
- Gate One
运维堡垒机介绍: 运维堡垒机的理念起源于跳板机.2000年左右,高端行业用户为了对运维人员的远程登录进行集中管理,会在机房里部署跳板机.跳板机就是一台服务器,维护人员在维护过程中,首先要统一登录到这台 ...