使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序

不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址

本博文翻译自:

http://l-knowtech.com/2017/08/28/first-crud-application-asp-net-core-mvc-using-entity-framework-core/


本文打算使用Entity Framework Core解释ASP.NET Core MVC中的基本创建,读取,更新和删除(CRUD)操作。我们使用Entity Framework Code First的方法开发应用程序 ,要设置ASP.NET Core MVC应用程序的开发环境,我们遵循本文中开始使用 ASP.NET Core MVC.的步骤。应用程序使用一个名为Book的实体来执行CRUD操作,并做一些简单的演示。

更多精彩内容

  1. 开始使用 ASP.NET Core MVC

创建数据库


这个应用程序采用的是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表示被配置的实体。它使用方法定义每个字段的配置。让我们看一下在前面的代码中使用的一些方法。

  1. **HasKey: **

    它设置了构成主键的实体属性。
  2. 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连接数据库

我们定义了一个带有上下文的数据模型。现在,我们定义了数据库和上下文之间的连接。我们必须遵循以下步骤,在应用程序中使用上下文。

  1. 我们定义一个连接字符串,以便将上下文连接到数据库。打开appsetting.json文件,并根据以下代码片段定义连接字符串。
"ConnectionStrings": {
"DefaultConnection": "Data Source=DESKTOP-RG33QHE;Initial Catalog=ApplicationDb;User ID=sa; Password=admin123"
}

它类似于web.config。它存储配置级别设置,如连接字符串、SMTP、域名等。

  1. 应用程序配置从Startup类初始化。由于这个应用程序使用了Entity Framework Core,所以我们在使用中添加了两个名称空间。下面的代码片段是相同的。
using FirstCRUDApplication.DbEntities;
using Microsoft.EntityFrameworkCore;
  1. 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>

现在,我们需要遵循从数据模型创建新数据库的步骤。这些都是

  1. 保存更改并构建项目。
  2. 打开解决方案文件夹位置。在解决方案浏览器中,右键单击该项目并从上下文菜单中选择打开文件资源管理器。
  3. 如下图所示在地址栏中写入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(增删改查)的应用程序的更多相关文章

  1. 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 ...

  2. EF(Entity Framework)通用DBHelper通用类,增删改查以及列表

    其中 通用类名:DBhelper 实体类:UserInfo 1 //新增 2 DBHelper<UserInfo> dbhelper = new DBHelper<UserInfo& ...

  3. ASP.NET MVC+EasyUI+Entity FrameWork 整合开发

    本文详细讲解怎么用ASP.NET MVC+EasyUI+Entity FrameWork 来开发一个项目 对于ASP.NET MVC的Jscript库,主要引用 <script type=.mi ...

  4. 手把手教你ASP.NET Core:使用Entity Framework Core进行增删改查

    新建表Todo,如图 添加模型类 在"解决方案资源管理器"中,右键单击项目. 选择"添加" > "新建文件夹". 将文件夹命名为 Mo ...

  5. Mvc5+Entity Framework6 之二----在MVC中用Entity Framework实现基本的CRUD

    目标:创建控制器和视图的代码,实现CRUD(创建,读取,更新,删除)功能 创建一个详细信息页 控制器为Students的Index页生成的代码排除Enrollments属性在外,因为该属性中关联着一个 ...

  6. abp(net core)+easyui+efcore实现仓储管理系统——展现层实现增删改查之列表视图(七)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  7. 基于Entity Framework的自定义分页,增删改的通用实现

    简介 之前写个一个基于Dapper的分页实现,现在再来写一个基于Entity Framework的分页实现,以及增删改的通用实现. 代码 还是先上代码:https://github.com/jinwe ...

  8. MVC模式:实现数据库中数据的增删改查功能

    *.数据库连接池c3p0,连接mysql数据库: *.Jquery使用,删除时跳出框,确定是否要删除: *.使用EL和JSTL,简化在jsp页面中插入的java语言 1.连接数据库 (1)导入连接数据 ...

  9. Entity Framework 学习系列(4) - EF 增删改

    目录 写在前面 一.开发环境 二.创建项目 三.新增 1.单表新增 2.批量新增 3.多表新增 四.编辑 1.先查询,后编辑 2.创建实体,后编辑 五.删除 写在前面 在上一小节中,学习了如何 通过C ...

随机推荐

  1. Java 9 揭秘(17. Reactive Streams)

    Tips 做一个终身学习的人. 在本章中,主要介绍以下内容: 什么是流(stream) 响应式流(Reactive Streams)的倡议是什么,以及规范和Java API 响应式流在JDK 中的AP ...

  2. 关于position

    一.position 一)语法: 看了那么久的语法,终于到了讲正题的时间了. 二)定位 1.相对定位:相对元素自己在没有定位之前的位置进行位移,元素仍然保留还没有原来的位置. 特性: 1)不脱离文档流 ...

  3. HTML5 开发APP( 支付宝支付)

    我们搞app有一个重要的功能那就是支付功能.无论是微信支付,支付宝,还是银联支付总要有一样支付手段来支持我们网上付款.实现完整的功能.我们公司app的支付方式经过大家开会讨论选择了支付宝支付(其实是当 ...

  4. 跨主机网络概述 - 每天5分钟玩转 Docker 容器技术(48)

    前面已经学习了 Docker 的几种网络方案:none.host.bridge 和 joined 容器,它们解决了单个 Docker Host 内容器通信的问题.本章的重点则是讨论跨主机容器间通信的方 ...

  5. vue获取下拉框值

    vue获取下拉框的值,用vue-modle,只有点击下拉框的值才会赋值到下拉框中,初始时下拉框没有数据,而改用$event就不会出现这样的问题,下面看代码以及图解: v-model解决方式: < ...

  6. 测试环境-memcached安装与说明

    一,下载memcached和libevent安装包: 1,Memcache用到了libevent这个库用于Socket的处理,所以还需要安装libevent (这两个包百度上都能找到) 二,安装lib ...

  7. curl---一款实用的URL命令行网络通讯工具/库

    最近一段时间在看朴灵翻译的<深入浅出nodejs>,里面有提到一种脱离浏览器的客户端网络通讯工具,curl命令,自己在电脑上试了一下,感觉非常好用,而且莫名的感觉这是一个非常强大的网络工具 ...

  8. hdu--2084--dp--数塔

    #include<iostream> #include<cstring> using namespace std; ; }; void dp(int,int); int n; ...

  9. Rabin-Karp【转载】

    问题描述: Rabin-Karp的预处理时间是O(m),匹配时间O( ( n - m + 1 ) m )既然与朴素算法的匹配时间一样,而且还多了一些预处理时间,那为什么我们还要学习这个算法呢?虽然Ra ...

  10. Eclipse中tomcat配置

    配置这两个东西 tomcat,在eclipse中启动 tomcat 才会可以访问   来自为知笔记(Wiz)