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

使用ASP.NET Core MVC 和 Entity Framework Core开发项目

  • 商品编号:
    #36018150_360
    • 原价:
      免费
    • 会员价:
      免费
  • 分类:
    • V1.0.0
  • 数量:

购物车中已存在此商品,请在购物车中操作单击跳转购物车

  • 开发者:返回主页 东城慕水
  • 开发语言:C#
  • 开发环境:Visual Studio
  • 数据库:SqlServer
  • 商品架构:B/S
  • 代码管理工具:github
  • 编码格式:utf-8
  • 是否开源:是
  • 开源协议:BSD

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

    本博文翻译自:http://l-knowtech.com/2017/08/28/first-crud-application-asp-net-core-mvc-using-entity-framework-core/

    本文打算使用ASP.NET Core MVC和Entity Framework Core在ASP中解释基本的创建、读取、更新和删除(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数据库程序

创建数据实体模型

应用程序在单个实体上执行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实体的配置创建。定义配置有两种选择,一种是Data Annotation ,另一种是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&lt;CRUDContext&gt; options) : base(options)
        {
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            new BookMap(modelBuilder.Entity&lt;Book&gt;());
        }
    }
}

使用EF连接数据库

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

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

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

  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&lt;CRUDContext&gt;(options =&gt; options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        }

使用EF Migration初始化数据库

我们使用Entity Framework Core Migration来根据数据模型创建一个数据库。为了执行迁移,我们可以使用Package Manager Console(PMS)和Command Line Interface(CLI)。

Entity Framework Core工具CLI提供了 Microsoft.EntityFrameworkCore.Tool.DotNet 。要安装这个包,我们不能使用安装包命令或包管理器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

EF-Migration

图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所示。

ASP-NET-Core-MVC-Application-Listing

图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。

Add-Edit-ASP-NET-Core-MVC

图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中删除一本书。

ASP-NET-Core-MVC-Delete

图4:确认删除一本书

结论

本文使用ASP.NET Core和Entity Framework Core与code first开发应用程序并在模型弹出窗口中执行数据CRUD操作。


权利声明:本站所有商品信息、客户评价等信息是初心商城重要的数据资源,未经许可,禁止非法转载使用。 注:本站商品信息均来自初心商城,其真实性、准确性和合法性由初心商城负责。

                  初心源说明:初心商城主要为程序员提供开发基础的代码源以及成熟项目,网站中所有的商品有提供收费版本的, 也有提供免费版本的,按照大家各自不同的需求进行购买。实实在在的让程序员只用专注于自己的业务实现你的小梦想, 如果您对我们的成果表示认同并且觉得对你有所帮助我们愿意接受来自各方面的支持^_^。

                  支持:用手机扫描二维码支付

                  支付宝支持我们 微信支持我们

                  您的支持将被用于:
                  1、持续深入的上传更多更好的源代码
                  2、建立更加完善的技术社区
                  3、完善现在系统出现各种问题
                  4、购买域名和租赁服务器

                  1、交易规则

                  2、发货方式

                  1、自动:在上方保障服务中标有自动发货的商品,拍下后,将会自动收到来自卖家的商品获取(下载)链接

                  2、手动:在上方保障服务中标有手动发货的商品,拍下后,卖家会收到邮件,也可通过QQ或订单中的电话联系对方。

                  3、退款说明

                  1、描述:源码描述(含标题)与实际源码不一致的(例:描述PHP实际为ASP、描述的功能实际缺少、版本不符等)

                  2、演示:有演示站时,与实际源码小于95%一致的(但描述中有"不保证完全一样、有变化的可能性"类似显著声明的除外)

                  3、发货:手动发货源码,在卖家未发货前,已申请退款的

                  4、服务:卖家不提供安装服务或需额外收费的(但描述中有显著声明的除外)

                  5、其它:如质量方面的硬性常规问题等

                  备注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。交易中的商品,卖家无法对描述进行修改!

                  4、注意事项

                  1、客户买完之后未确认收货,将不会收到下载地址和下载码,确认收货之后才能收到下载地址和下载码。

                  2、在未拍下前,双方在QQ上所商定的内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准);

                  3、在商品同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外);

                  4、在没有"无任何正当退款依据"的前提下,写有"一旦售出,概不支持退款"等类似的声明,视为无效声明;

                  5、虽然交易产生纠纷的几率很小,但请尽量保留如聊天记录这样的重要信息,以防产生纠纷时出现问题不明确的情况。

                  5、交易声明

                  1、本站作为直卖平台,依据交易合同(商品描述、交易前商定的内容)来保障交易的安全及买卖双方的权益;

                  2、非平台线上交易的商品,出现任何后果均与本站无关;无论卖家以何理由要求线下交易的,请联系管理举报。

                  初心Logo

                  初心商城| 初心系列| 初心博客| 初心公告| 系统反馈

                  © 2016-2018 山西米立信息技术有限公司 保留所有权利 京ICP备16055626号
                  违法和不良信息举报电话:186-2950-9347,本网站所列数据,除特殊说明,所有数据均出自我工作室
                  本网站兼容所有主流浏览器,不支持手机自适应