Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

ASP.NET Core 打造一个简单的图书馆管理系统(七)外借/阅览图书信息的增删改查

NanaseRuri 2019-02-01 17:49:00 阅读数:223 评论数:0 点赞数:0 收藏数:0

前言:

本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作。

本系列文章主要参考资料:

微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows

《Pro ASP.NET MVC 5》、《锋利的 jQuery》

 

当此系列文章写完后会在一周内推出修正版。

 

此系列皆使用 VS2017+C/# 作为开发环境。如果有什么问题或者意见欢迎在留言区进行留言。 

项目 github 地址:https://github.com/NanaseRuri/LibraryDemo

 

 

本章内容:通过模态窗口确认是否提交表单、select 元素、表单提交数组、checkbox、关闭窗口前确认、EF 修改主键

 

 

 

一、外借/阅览图书信息首页

这里的实现和上一章大致一致,但这里我打算通过前面的 BookDetail 页面进入到这个页面:

首先创建一个视图模型同时保存 BookDetail 的信息并传递 IEnumerable 以便对对应 BookDetails 的外借/阅览图书信息进行展示:1 public classBookEditModel2 {3 public BookDetails BookDetails { get; set; }4 public IEnumerable Books { get; set; }5 }

 

对应 BookDetail 的外借/阅览图书信息首页:1 [Authorize(Roles = "Admin")]2 public IActionResult Books(stringisbn)3 {4 BookEditModel model = newBookEditModel()5 {6 Books = _context.Books.Where(b => b.ISBN ==isbn),7 BookDetails = _context.BooksDetail.FirstOrDefault(b => b.ISBN ==isbn)8 };9 if (model.BookDetails==null)10 {11 TempData["message"] = "未找到目标书籍";12 return RedirectToAction("BookDetails");13 }14 returnView(model);15 }

 

视图:1 @using LibraryDemo.Models.DomainModels2 @model BookEditModel3 4 @{5 ViewData["Title"] = "外借/阅览书籍信息";6 Book temp = newBook();7 }8 9 27 28 41 42

《@Model.BookDetails.Name》

43
44 45 @if (TempData["message"] != null)46 {47

@TempData["message"]

48
49
50 }51 52
53
54 添加外借书籍 55 56
57
58 59 60 61 62 63 64 65 66 67 68 69 70 71 @if (Model.Books.ToList().Count == 0)72 {73 74 }75 @foreach (var book inModel.Books)76 {77 78 79 80 81 82 83 84 85 86 87 }88 89
@Html.LabelFor(b => temp.BarCode)@Html.LabelFor(b => temp.Bookshelf)@Html.LabelFor(b => temp.BorrowTime)@Html.LabelFor(b => temp.MatureTime)@Html.LabelFor(b => temp.AppointedLatestTime)@Html.LabelFor(b => temp.State)@Html.LabelFor(b => temp.Keeper)
未有《@Model.BookDetails.Name》的外借/阅览书籍信息
@Html.DisplayFor(b => book.BarCode)@Html.DisplayFor(b => book.BookshelfId)@Html.DisplayFor(b => book.BorrowTime)@Html.DisplayFor(b => book.MatureTime)@Html.DisplayFor(b => book.AppointedLatestTime)@Html.DisplayFor(b => book.State)@Html.DisplayFor(b => book.Keeper.Name)
90

 

 结果:

 

 

二、添加的外借/阅览图书信息

在 21 行中使用了 Bind 特性,使在模型绑定过程中只绑定对应属性名的属性,防止了与其他数据的绑定。 Bind 特性中的属性名区分大小写,与表单中的 input 的 name 一一对应。

26 行使用 .AsNoTracking 告诉 EF 在查询时禁用更改跟踪提高性能,对不需要进行更改的数据的查询都可以带有该方法。

32 行对表单上传的数据进行检验以确认来自同一本书。

34 行中使用 Include 方法告诉 EF 使返回的书架包含架上书本的信息,使 bookshelf.Books 返回一个 ICollection 实例而不是空 ICollection 以将新的外借/阅览图书信息添加其中。1 [Authorize(Roles = "Admin")]2 public IActionResult AddBook(stringisbn)3 {4 BookDetails bookDetails = _context.BooksDetail.FirstOrDefault(b => b.ISBN ==isbn);5 if (bookDetails == null)6 {7 return RedirectToAction("BookDetails", new { isbn =isbn });8 }9 Book book = newBook()10 {11 ISBN =bookDetails.ISBN,12 Name =bookDetails.Name,13 FetchBookNumber =bookDetails.FetchBookNumber14 };15 returnView(book);16 }17 18 [HttpPost]19 [ValidateAntiForgeryToken]20 [Authorize(Roles = "Admin")]21 public async Task AddBook([Bind("ISBN,Name,FetchBookNumber,BarCode,BookshelfId,State")]Book book)22 {23 if(ModelState.IsValid)24 {25 BookDetails bookDetails = _context.BooksDetail.FirstOrDefault(b => b.ISBN ==book.ISBN);26 Book existBook = _context.Books.AsNoTracking().FirstOrDefault(b => b.BarCode ==book.BarCode);27 if (existBook != null)28 {29 TempData["message"] = $"已有二维码为{book.BarCode}的书籍《{existBook.Name}》";30 return RedirectToAction("AddBook", new {isbn =book.ISBN});31 }32 if (bookDetails.Name ==book.Name)33 {34 Bookshelf bookshelf = _context.Bookshelves.Include(b=>b.Books).FirstOrDefault(b => b.BookshelfId ==book.BookshelfId);35 if (bookshelf != null)36 {37 book.Sort =bookshelf.Sort;38 book.Location =bookshelf.Location;39 bookshelf.Books.Add(book);40 bookshelf.MaxFetchNumber = bookshelf.Books.Max(b =>b.FetchBookNumber);41 bookshelf.MinFetchNumber = bookshelf.Books.Min(b =>b.FetchBookNumber);42 }43 await_context.Books.AddAsync(book);44 await_context.SaveChangesAsync();45 TempData["message"] = $"《{book.Name}》 {book.BarCode} 添加成功";46 return RedirectToAction("Books", new { isbn =book.ISBN });47 }48 }49 returnView(book);50 }

 

 视图:1 @using LibraryDemo.Models.DomainModels2 @model LibraryDemo.Models.DomainModels.Book3 4 @{5 ViewData["Title"] = "AddBook";6 }7 8 19 20

@($"为《{Model.Name}》添加借阅/阅览书籍信息")

21
22
23 @if (TempData["message"] != null)24 {25

@TempData["message"]

26
27
28 }29 30 @Html.ValidationSummary(false, "", new { @class = "text-danger"})31
32
33 @Html.LabelFor(b =>b.ISBN)34 35
36
37 @Html.LabelFor(b =>b.Name)38 39
40
41 @Html.LabelFor(b =>b.FetchBookNumber)42 43
44
45 @Html.LabelFor(b =>Model.BarCode)46 @Html.EditorFor(b =>Model.BarCode)47
48
49 @Html.LabelFor(b =>Model.BookshelfId)50 @Html.EditorFor(b =>Model.BookshelfId)51
52
53 @Html.LabelFor(b =>Model.State)54 @Html.DropDownListFor(b=>Model.State,Enum.GetValues(typeof(BookState)).Cast().Select(state => 55 {56 string enumVal = Enum.GetName(typeof(BookState), state);57 stringdisplayVal;58 switch(enumVal)59 {60 case "Normal":61 displayVal = "可借阅";62 break;63 case "Readonly":64 displayVal = "馆内阅览";65 break;66 case "Borrowed":67 displayVal = "已借出";68 break;69 case "ReBorrowed":70 displayVal = "被续借";71 break;72 case "Appointed":73 displayVal = "被预约";74 break;75 default:76 displayVal = "";77 break;78 }79 return newSelectListItem()80 {81 Text=displayVal,82 Value =enumVal83 };84 }))85
86
87 88

 

 

 

三、移除外借/阅览图书信息

 此处实现与之前移除书籍信息大致一致,但额外接受一个 isbn 参数用来返回原 isbn 的外借/阅览图书信息首页:1 [Authorize(Roles = "Admin")]2 [HttpPost]3 [ValidateAntiForgeryToken]4 public async Task RemoveBooks(IEnumerable barcodes, stringisbn)5 {6 StringBuilder sb = newStringBuilder();7 foreach (var barcode inbarcodes)8 {9 Book book = _context.Books.First(b => b.BarCode ==barcode);10 _context.Books.Remove(book);11 sb.AppendLine($"{book.BarCode} 移除成功");12 }13 await_context.SaveChangesAsync();14 TempData["message"] =sb.ToString();15 return RedirectToAction("Books", new { isbn =isbn });16 }

 

 

四、增删总结果:

 

 

 

五、编辑借阅/阅览书籍信息:

在此设置 BarCode 可以被修改,由于修改主键时会导致 EF 的映射失败,因此EF 不支持直接修改主键,但是可以先将原数据删除再进行添加变相修改主键。

POST 的方法中额外接受一个 BarCode 用来保留原书籍信息。1 [Authorize(Roles = "Admin")]2 public IActionResult EditBook(stringbarcode)3 {4 Book book = _context.Books.First(b => b.BarCode ==barcode);5 returnView(book);6 }7 8 [HttpPost]9 [Authorize(Roles = "Admin")]10 [ValidateAntiForgeryToken]11 public async Task EditBook(string oldBarCode,[Bind("BarCode,BookshelfId,BorrowTime,Name,KeeperId,AppointedLatestTime")]Book book)12 {13 if(ModelState.IsValid)14 {15 Book oldBook = _context.Books.FirstOrDefault(b => b.BarCode ==oldBarCode);16 if (oldBook == null)17 {18 ViewBag["message"] = $"不存在二维码为{oldBarCode}的书籍";19 return RedirectToAction("BookDetails");20 }21 22 if (oldBook.Name ==book.Name)23 {24 book.ISBN =oldBook.ISBN;25 book.FetchBookNumber =oldBook.FetchBookNumber;26 Bookshelf bookshelf = _context.Bookshelves.Include(b => b.Books).FirstOrDefault(b => b.BookshelfId ==book.BookshelfId);27 if (bookshelf != null)28 {29 book.Sort =bookshelf.Sort;30 book.Location =bookshelf.Location;31 bookshelf.Books.Remove(oldBook);32 bookshelf.Books.Add(book);33 }34 35 _context.Books.Remove(oldBook);36 _context.Books.Add(book);37 await_context.SaveChangesAsync();38 TempData["message"] = "修改成功";39 return RedirectToAction("Books", new { isbn =oldBook.ISBN });40 }41 }42 returnView(book);43 }

 

1 @using LibraryDemo.Models.DomainModels2 @model LibraryDemo.Models.DomainModels.Book3 4 @{5 ViewData["Title"] = "EditBook";6 }7 8 19 20

编辑外借书籍

21
22

《@Model.Name》

23
24

原二维码:@Model.BarCode

25
26 @Html.ValidationSummary(false,"",new{@class="text-danger"})27 28
29 30 31
32 @Html.LabelFor(b =>b.BarCode)33 @Html.EditorFor(b =>b.BarCode)34
35
36 @Html.LabelFor(b =>b.BookshelfId)37 @Html.EditorFor(b =>b.BookshelfId)38
39
40 @Html.LabelFor(b =>b.BorrowTime)41 @Html.EditorFor(b =>b.BorrowTime)42
43
44 @Html.LabelFor(b =>b.KeeperId)45 @Html.EditorFor(b=>b.KeeperId)46
47
48 @Html.LabelFor(b =>b.AppointedLatestTime)49 @Html.EditorFor(b =>b.AppointedLatestTime)50
51
52 @Html.LabelFor(b =>b.State)53 @Html.DropDownListFor(b => b.State, Enum.GetValues(typeof(BookState)).Cast().Select(state => 54 {55 string enumVal = Enum.GetName(typeof(BookState), state);56 stringdisplayVal;57 switch(enumVal)58 {59 case "Normal":60 displayVal = "可借阅";61 break;62 case "Readonly":63 displayVal = "馆内阅览";64 break;65 case "Borrowed":66 displayVal = "已借出";67 break;68 case "ReBorrowed":69 displayVal = "被续借";70 break;71 case "Appointed":72 displayVal = "被预约";73 break;74 default:75 displayVal = "";76 break;77 }78 return newSelectListItem()79 {80 Text =displayVal,81 Value =enumVal,82 Selected = Model.State.ToString() ==enumVal83 };84 }))85
86
87 88

 

 

 

 

版权声明
本文为[NanaseRuri]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/gokoururi/p/10344146.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领