ASP.NET Core 打造一个简单的图书馆管理系统(五)初始化书籍信息

前言:

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

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

微软文档: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

本章内容:自定义 HtmlHelper、Session 的使用、分页、数据库初始化器、取消 int 主键自动增长

一、对图书信息的域模型进行修改

由于在此处我使用了二维码作为主键,一个二维码不可能同时放在不同的书架上,因此重写之前建立的多对多的模型。

移除 BookMiddle,去除 Book类 中的 ICollection<BookMiddle> 字段,改为 Bookshelf 字段。

 1     public class Book
 2     {                                
 3         /// <summary>
 4         /// 二维码
 5         /// </summary>
 6         [Key]
 7         public string BarCode { get; set; }
 8 
 9         public string ISBN { get; set; }
10 
11         /// <summary>
12         /// 书名
13         /// </summary>
14         [Required]
15         public string Name { get; set; }         
16 
17         /// <summary>
18         /// 取书号
19         /// </summary>
20         public string FetchBookNumber { get; set; }
21 
22         /// <summary>
23         /// 所在书架
24         /// </summary>
25         //public Bookshelf Bookshelf { get; set; }
26         public Bookshelf Bookshelf { get; set; }
27 
28         /// <summary>
29         /// 借出时间
30         /// </summary>
31         public DateTime? BorrowTime { get; set; }
32 
33         /// <summary>
34         /// 到期时间
35         /// </summary>
36         public DateTime? MatureTime { get; set; } 
37 
38         /// <summary>
39         /// 预约最晚借书日期
40         /// </summary>
41         public DateTime? AppointedLatestTime { get; set; }
42 
43         /// <summary>
44         /// 借阅状态
45         /// </summary>
46         public BookState State { get; set; }        
47 
48         /// <summary>
49         /// 持有者,指定外键
50         /// </summary>
51         public Student Keeper { get; set; }
52     }
View Code

移除 Bookshelf 类中的  ICollection<BookMiddle> 字段,改为 ICollection<Book> 字段

 1     public class Bookshelf
 2     {
 3         /// <summary>
 4         /// 书架ID
 5         /// </summary>
 6         [Key]
 7         public int BookshelfId { get; set; }
 8 
 9         /// <summary>
10         /// 书架的书籍类别
11         /// </summary>
12 
13         [Required]
14         public string Sort { get; set; }               
15         /// <summary>
16         /// 最小取书号
17         /// </summary>
18         [Required]
19         public string MinFetchNumber { get; set; }
20         [Required]
21         public string MaxFetchNumber { get; set; }
22 
23         /// <summary>
24         /// 书架位置
25         /// </summary>
26         [Required]
27         public string Location { get; set; }
28 
29         /// <summary>
30         /// 全部藏书
31         /// </summary>
32         public ICollection<Book> Books { get; set; }
33     }
View Code

为了能够给书籍添加缩略图以及更方便的编写逻辑,为 Book 和 BookDetail 添加多个字段:

 1     /// <summary>
 2     /// 用于借阅的书籍信息
 3     /// </summary>    
 4     public class Book
 5     {                                
 6         /// <summary>
 7         /// 二维码
 8         /// </summary>
 9         [Key][Required(ErrorMessage = "未填写二维码")]
10         [Display(Name = "二维码")]
11         public string BarCode { get; set; }
12 
13         public string ISBN { get; set; }
14 
15         /// <summary>
16         /// 书名
17         /// </summary>
18         [Required]
19         [Display(Name = "书名")]
20         public string Name { get; set; }
21 
22         /// <summary>
23         /// 取书号
24         /// </summary>
25         [Display(Name = "取书号")]
26         public string FetchBookNumber { get; set; }
27 
28         /// <summary>
29         /// 所在书架
30         /// </summary>
31         public Bookshelf Bookshelf { get; set; }
32 
33         [Display(Name = "书架号")]
34         public int BookshelfId { get; set; }
35 
36         /// <summary>
37         /// 借出时间
38         /// </summary>
39         [Display(Name = "借出时间")]
40         public DateTime? BorrowTime { get; set; }
41 
42         /// <summary>
43         /// 到期时间
44         /// </summary>
45         [Display(Name = "到期时间")]
46         public DateTime? MatureTime { get; set; }
47 
48         /// <summary>
49         /// 预约最晚借书日期
50         /// </summary>
51         [Display(Name = "预约取书时间")]
52         public DateTime? AppointedLatestTime { get; set; }
53 
54         /// <summary>
55         /// 借阅状态
56         /// </summary>
57         [Display(Name = "书籍状态")]
58         public BookState State { get; set; }
59 
60         /// <summary>
61         /// 持有者,指定外键
62         /// </summary>
63         public Student Keeper { get; set; }
64         [Display(Name = "持有者学号")]
65         public string KeeperId { get; set; }
66 
67         [Display(Name = "位置")]
68         public string Location { get; set; }
69 
70         [Display(Name = "分类")]
71         public string Sort { get; set; }
72     }
 1     /// <summary>
 2     /// 书籍自身的详细信息
 3     /// </summary>
 4     public class BookDetails
 5     {
 6         [Key]
 7         public string ISBN { get; set; }
 8         [Required]
 9         public string Name { get; set; }
10         [Required]
11         public string Author { get; set; }
12         [Required]
13         public string Press { get; set; }
14         [Required]
15         public string FetchBookNumber { get; set; }        
16         /// <summary>
17         /// 出版时间
18         /// </summary>
19         [Required]
20         public DateTime PublishDateTime{ get; set; }
21 
22         /// <summary>
23         /// 书籍版本
24         /// </summary>
25         [Required]
26         public int Version { get; set; }
27 
28         /// <summary>
29         /// 载体形态,包括页数、媒介等信息
30         /// </summary>
31         public string SoundCassettes { get; set; }
32 
33         /// <summary>
34         /// 简介
35         /// </summary>
36         public string Description { get; set; }
37 
38 
39         /// <summary>
40         /// 缩略图
41         /// </summary>
42         public byte[] ImageData { get; set; }
43         public string ImageMimeType { get; set; }
44     }

由于 EF 会自动将 int 类型的主键设置为自动增长,因此自定义 Bookshelf 的 ID 在插入数据库时会报错,在此需添加修饰 [DatabaseGenerated(DatabaseGeneratedOption.None)] 告知 ef 取消该设置:

 1     public class Bookshelf
 2     {
 3         /// <summary>
 4         /// 书架ID
 5         /// </summary>
 6         [Key]
 7         //不自动增长
 8         [DatabaseGenerated(DatabaseGeneratedOption.None)] 
 9         public int BookshelfId { get; set; }
10 
11         /// <summary>
12         /// 书架的书籍类别
13         /// </summary>
14 
15         [Required]
16         public string Sort { get; set; }               
17         /// <summary>
18         /// 最小取书号
19         /// </summary>
20         [Required]
21         public string MinFetchNumber { get; set; }
22         [Required]
23         public string MaxFetchNumber { get; set; }
24 
25         /// <summary>
26         /// 书架位置
27         /// </summary>
28         [Required]
29         public string Location { get; set; }
30 
31         /// <summary>
32         /// 全部藏书
33         /// </summary>
34         public ICollection<Book> Books { get; set; }
35     }

然后添加迁移并更新数据库,若更新失败在此选择移除数据库以及迁移再执行该步骤,生产中应当备份原文件:

1     cd LibraryDemo
2     add-migration RemoveBookMiddle -c LibraryDemo.Data.LendingInfoDbContext
3     update-database -c LibraryDemo.Data.LendingInfoDbContext

新建 BookInitiator 用于初始化该数据库,在这里会报一个 Book 重复主键的错误,不知道为什么但是数据确实全都插进去了:

  1 public class BookInitiator
  2     {
  3         public static async Task BookInitial(IServiceProvider serviceProvider)
  4         {
  5             LendingInfoDbContext context = serviceProvider.GetRequiredService<LendingInfoDbContext>();
  6             if (!context.Books.Any() || !context.Bookshelves.Any())
  7             {
  8                 Bookshelf[] bookshelfs = new[]
  9                 {
 10                     new Bookshelf()
 11                     {
 12                         BookshelfId = 1,
 13                         Location = "主校区",
 14                         Sort = "计算机"
 15                     },
 16                     new Bookshelf()
 17                     {
 18                         BookshelfId = 2,
 19                         Location = "主校区",
 20                         Sort = "文学"
 21                     },
 22                     new Bookshelf()
 23                     {
 24                         BookshelfId = 3,
 25                         Location = "东校区",
 26                         Sort = "计算机"
 27                     },
 28                     new Bookshelf()
 29                     {
 30                         BookshelfId = 4,
 31                         Location = "阅览室",
 32                         Sort = "文学"
 33                     },
 34                     new Bookshelf()
 35                     {
 36                         BookshelfId = 5,
 37                         Location = "阅览室",
 38                         Sort = "计算机"
 39                     },
 40                 };
 41 
 42                 Book[] books = new[]
 43                 {
 44                     new Book()
 45                     {
 46                         Name = "精通ASP.NET MVC 5",
 47                         BarCode = "001100987211",
 48                         ISBN = "978-7-115-41023-8",
 49                         State = BookState.Normal,
 50                         FetchBookNumber = "TP393.092 19",
 51                         Location = "主校区",
 52                         Sort = "计算机"
 53                     },
 54                     new Book()
 55                     {
 56                         Name = "精通ASP.NET MVC 5",
 57                         BarCode = "001100987212",
 58                         ISBN = "978-7-115-41023-8",
 59                         State = BookState.Normal,
 60                         FetchBookNumber = "TP393.092 19",
 61                         Location = "主校区",
 62                         Sort = "计算机"
 63                     },
 64                     new Book()
 65                     {
 66                         Name = "精通ASP.NET MVC 5",
 67                         BarCode = "001100987213",
 68                         ISBN = "978-7-115-41023-8",
 69                         State = BookState.Normal,
 70                         FetchBookNumber = "TP393.092 19",
 71                         Location = "东校区",
 72                         Sort = "计算机"
 73                     },
 74                     new Book()
 75                     {
 76                         Name = "精通ASP.NET MVC 5",
 77                         BarCode = "001100987214",
 78                         ISBN = "978-7-115-41023-8",
 79                         State = BookState.Readonly,
 80                         FetchBookNumber = "TP393.092 19",
 81                         Location = "阅览室",
 82                         Sort = "计算机"
 83                     },
 84                     new Book()
 85                     {
 86                         Name = "Entity Framework实用精要",
 87                         BarCode = "001101279682",
 88                         ISBN = "978-7-302-48593-3",
 89                         State = BookState.Normal,
 90                         FetchBookNumber = "TP393.09 447",
 91                         Location = "主校区",
 92                         Sort = "计算机"
 93                     },
 94                     new Book()
 95                     {
 96                         Name = "Entity Framework实用精要",
 97                         BarCode = "001101279683",
 98                         ISBN = "978-7-302-48593-3",
 99                         State = BookState.Normal,
100                         FetchBookNumber = "TP393.09 447",
101                         Location = "主校区",
102                         Sort = "计算机"
103                     },
104                     new Book()
105                     {
106                         Name = "Entity Framework实用精要",
107                         BarCode = "001101279684",
108                         ISBN = "978-7-302-48593-3",
109                         State = BookState.Normal,
110                         FetchBookNumber = "TP393.09 447",
111                         Location = "东校区",
112                         Sort = "计算机"
113                     },
114                     new Book()
115                     {
116                         Name = "Entity Framework实用精要",
117                         BarCode = "001101279685",
118                         ISBN = "978-7-302-48593-3",
119                         State = BookState.Normal,
120                         FetchBookNumber = "TP393.09 447",
121                         Location = "东校区",
122                         Sort = "计算机"
123                     },
124                     new Book()
125                     {
126                         Name = "Entity Framework实用精要",
127                         BarCode = "001101279686",
128                         ISBN = "978-7-302-48593-3",
129                         State = BookState.Normal,
130                         FetchBookNumber = "TP393.09 447",
131                         Location = "阅览室",
132                         Sort = "计算机"
133                     },
134                     new Book()
135                     {
136                         Name = "Rails 5敏捷开发",
137                         BarCode = "001101290497",
138                         ISBN = "978-7-5680-3659-7",
139                         State = BookState.Normal,
140                         FetchBookNumber = "TP393.09 448",
141                         Location = "主校区",
142                         Sort = "计算机"
143                     },
144                     new Book()
145                     {
146                         Name = "Rails 5敏捷开发",
147                         BarCode = "001101290498",
148                         ISBN = "978-7-5680-3659-7",
149                         State = BookState.Normal,
150                         FetchBookNumber = "TP393.09 448",
151                         Location = "主校区",
152                         Sort = "计算机"
153                     },
154                     new Book()
155                     {
156                         Name = "Rails 5敏捷开发",
157                         BarCode = "001101290499",
158                         ISBN = "978-7-5680-3659-7",
159                         State = BookState.Readonly,
160                         FetchBookNumber = "TP393.09 448",
161                         Location = "主校区",
162                         Sort = "计算机"
163                     },
164                     new Book()
165                     {
166                         Name = "你必须掌握的Entity Framework 6.x与Core 2.0",
167                         BarCode = "001101362986",
168                         ISBN = "978-7-5680-3659-7",
169                         State = BookState.Normal,
170                         FetchBookNumber = "TP393.09 452",
171                         Location = "主校区",
172                         Sort = "计算机"
173                     },
174                     new Book()
175                     {
176                         Name = "你必须掌握的Entity Framework 6.x与Core 2.0",
177                         BarCode = "001101362987",
178                         ISBN = "978-7-5680-3659-7",
179                         State = BookState.Readonly,
180                         FetchBookNumber = "TP393.09 452",
181                         Location = "主校区",
182                         Sort = "计算机"
183                     },
184                     new Book()
185                     {
186                         Name = "毛选. 第一卷",
187                         BarCode = "00929264",
188                         ISBN = "7-01-000922-8",
189                         State = BookState.Normal,
190                         FetchBookNumber = "A41 1:1",
191                         Location = "主校区",
192                         Sort = "文学"
193                     },
194                     new Book()
195                     {
196                         Name = "毛选. 第一卷",
197                         BarCode = "00929265",
198                         ISBN = "7-01-000922-8",
199                         State = BookState.Normal,
200                         FetchBookNumber = "A41 1:1",
201                         Location = "主校区",
202                         Sort = "文学"
203                     },
204                     new Book()
205                     {
206                         Name = "毛选. 第一卷",
207                         BarCode = "00929266",
208                         ISBN = "7-01-000922-8",
209                         State = BookState.Readonly,
210                         FetchBookNumber = "A41 1:1",
211                         Location = "阅览室",
212                         Sort = "文学"
213                     },
214                     new Book()
215                     {
216                         Name = "毛选. 第二卷",
217                         BarCode = "00929279",
218                         ISBN = "7-01-000915-5",
219                         State = BookState.Normal,
220                         FetchBookNumber = "A41 1:2",
221                         Location = "主校区",
222                         Sort = "文学"
223                     },
224                     new Book()
225                     {
226                         Name = "毛选. 第二卷",
227                         BarCode = "00929280",
228                         ISBN = "7-01-000915-5",
229                         State = BookState.Readonly,
230                         FetchBookNumber = "A41 1:2",
231                         Location = "阅览室",
232                         Sort = "文学"
233                     },
234                     new Book()
235                     {
236                         Name = "毛选. 第三卷",
237                         BarCode = "00930420",
238                         ISBN = "7-01-000916-3",
239                         State = BookState.Normal,
240                         FetchBookNumber = "A41 1:3",
241                         Location = "主校区",
242                         Sort = "文学"
243                     },
244                     new Book()
245                     {
246                         Name = "毛选. 第三卷",
247                         BarCode = "00930421",
248                         ISBN = "7-01-000916-3",
249                         State = BookState.Readonly,
250                         FetchBookNumber = "A41 1:3",
251                         Location = "阅览室",
252                         Sort = "文学"
253                     },
254                     new Book()
255                     {
256                         Name = "毛选. 第四卷",
257                         BarCode = "00930465",
258                         ISBN = "7-01-000925-2",
259                         State = BookState.Normal,
260                         FetchBookNumber = "A41 1:4",
261                         Location = "主校区",
262                         Sort = "文学"
263                     },
264                     new Book()
265                     {
266                         Name = "毛选. 第四卷",
267                         BarCode = "00930466",
268                         ISBN = "7-01-000925-2",
269                         State = BookState.Readonly,
270                         FetchBookNumber = "A41 1:4",
271                         Location = "阅览室",
272                         Sort = "文学"
273                     }
274                 };
275 
276                 BookDetails[] bookDetails = new[]
277                 {
278                     new BookDetails()
279                     {
280                         Author = "Admam Freeman",
281                         Name = "精通ASP.NET MVC 5",
282                         ISBN = "978-7-115-41023-8",
283                         Press = "人民邮电出版社",
284                         PublishDateTime = new DateTime(2016,1,1),
285                         SoundCassettes = "13, 642页 : 图 ; 24cm",
286                         Version = 1,
287                         FetchBookNumber = "TP393.092 19",
288                         Description = "ASP.NET MVC 5框架是微软ASP.NET Web平台的新进展。它提供了高生产率的编程模型,结合ASP.NET的全部优势,促成更整洁的代码架构、测试驱动开发和强大的可扩展性。本书涵盖ASP.NET MVC 5的所有开发优势技术,包括用C#属性定义路由技术及重写过滤器技术等。且构建MVC应用程序的用户体验也有本质上的改进。其中书里也专一讲解了用新Visual Studio 2013创建MVC应用程序时的技术和技巧。本书包括完整的开发工具介绍以及对代码进行辅助编译和调试的技术。本书还涉及流行的Bootstrap JavaScript库,该库现已被纳入到MVC 5之中,为开发人员提供更广泛的多平台CSS和HTML5选项,而不必像以前那样去加载大量的第三方库。"
289                     },
290                     new BookDetails()
291                     {
292                         Author = "吕高旭",
293                         Name = "Entity Framework实用精要",
294                         ISBN = "978-7-302-48593-3",
295                         Press = "清华大学出版社",
296                         PublishDateTime = new DateTime(2018,1,1),
297                         SoundCassettes = "346页 ; 26cm",
298                         Version = 1,
299                         FetchBookNumber = "TP393.09 447",
300                         Description = "本书通过介绍Entity Framework与 LINQ 开发实战的案例,以 Entity Framework 技术内容的讨论为主线,结合关键的 LINQ技巧说明,提供读者系统性学习 Entity Framework 所需的内容。本书旨在帮助读者进入 Entity Framework的世界,建立必要的技术能力,同时希望读者在完成本书的教学课程之后,能够更进一步地将其运用在实际的项目开发中。"
301                     },
302                     new BookDetails()
303                     {
304                         Author = "鲁比",
305                         Name = "Rails 5敏捷开发",
306                         ISBN = "978-7-5680-3659-7",
307                         Press = "华中科技大学出版社",
308                         PublishDateTime = new DateTime(2018,1,1),
309                         SoundCassettes = "xxi, 451页 : 图 ; 23cm",
310                         Version = 1,
311                         FetchBookNumber = "TP393.09 448",
312                         Description = "本书以讲解“购书网站”案例为主线, 逐步介绍Rails的内置功能。全书分为3部分, 第一部分介绍Rails的安装、应用程序验证、Rails框架的体系结构, 以及Ruby语言知识; 第二部分用迭代方式构建应用程序, 然后依据敏捷开发模式开展测试, 最后用Capistrano完成部署; 第三部分补充日常实用的开发知识。本书既有直观的示例, 又有深入的分析, 同时涵盖了Web开发各方面的知识, 堪称一部内容全面而又深入浅出的佳作。第5版增加了关于Rails 5和Ruby 2.2新特性和最佳实践的内容。"
313                     },
314                     new BookDetails()
315                     {
316                         Author = "汪鹏",
317                         Name = "你必须掌握的Entity Framework 6.x与Core 2.0",
318                         ISBN = "978-7-302-50017-9",
319                         Press = "清华大学出版社",
320                         PublishDateTime = new DateTime(2018,1,1),
321                         SoundCassettes = "X, 487页 : 图 ; 26cm",
322                         Version = 1,
323                         FetchBookNumber = "TP393.09 452",
324                         Description = "本书分为四篇,第一篇讲解Entity Framework 6.x的基础,包括数据库表的创建,数据的操作和数据加载方式。第二篇讲解Entity Framework 6.x进阶,包括基本原理和性能优化。第三篇讲解跨平台Entity Framework Core 2.x的基础知识和开发技巧。第四篇讲解在Entity Framework Core 2.x中解决并发问题,并给出实战开发案例。"
325                     },
326                     new BookDetails()
327                     {
328                         Author = "",
329                         Name = "毛选. 第一卷",
330                         ISBN = "7-01-000914-7",
331                         Press = "人民出版社",
332                         PublishDateTime = new DateTime(1991,1,1),
333                         SoundCassettes = "340页 : 肖像 ; 19厘米",
334                         FetchBookNumber = "A41 1:1",
335                         Version = 2,
336                         Description = "《毛选》是对20世纪中国影响最大的书籍之一。"
337                     },
338                     new BookDetails()
339                     {
340                         Author = "",
341                         Name = "毛选. 第二卷",
342                         ISBN = "7-01-000915-5",
343                         Press = "人民出版社",
344                         PublishDateTime = new DateTime(1991,1,1),
345                         SoundCassettes = "343-786页 : 肖像 ; 19厘米",
346                         Version = 2,
347                         FetchBookNumber = "A41 1:2",
348                         Description = "《毛选》是对20世纪中国影响最大的书籍之一。"
349                     },
350                     new BookDetails()
351                     {
352                         Author = "",
353                         Name = "毛选. 第三卷",
354                         ISBN = "7-01-000916-3",
355                         Press = "人民出版社",
356                         PublishDateTime = new DateTime(1991,1,1),
357                         SoundCassettes = "789Ł±1120页 ; 20厘米",
358                         FetchBookNumber = "A41 1:3",
359                         Version = 2,
360                         Description = "《毛选》是对20世纪中国影响最大的书籍之一。"
361                     },
362                     new BookDetails()
363                     {
364                         Author = "",
365                         Name = "毛选. 第四卷",
366                         ISBN = "7-01-000925-2",
367                         Press = "人民出版社",
368                         PublishDateTime = new DateTime(1991,1,1),
369                         SoundCassettes = "1123Ł±1517页 ; 20厘米",
370                         FetchBookNumber = "A41 1:4",
371                         Version = 2,
372                         Description = "《毛选》是对20世纪中国影响最大的书籍之一。"
373                     },
374                 };
375 
376                 var temp = from book in books
377                            from bookshelf in bookshelfs
378                            where book.Location == bookshelf.Location && book.Sort == bookshelf.Sort
379                            select new { BarCode = book.BarCode, BookshelfId = bookshelf.BookshelfId };
380 
381                 foreach (var bookshelf in bookshelfs)
382                 {
383                     bookshelf.Books=new List<Book>();
384                 }
385 
386                 foreach (var tem in temp)
387                 {
388                     Bookshelf targetShelf = bookshelfs.Single(bookshelf => bookshelf.BookshelfId == tem.BookshelfId);
389                     Book targetBook = books.Single(book => book.BarCode == tem.BarCode);
390                     targetShelf.Books.Add(targetBook);
391                 }
392 
393                 foreach (var bookshelf in bookshelfs)
394                 {
395                     bookshelf.MaxFetchNumber=bookshelf.Books.Max(b => b.FetchBookNumber);
396                     bookshelf.MinFetchNumber=bookshelf.Books.Min(b => b.FetchBookNumber);
397                 }
398 
399                 foreach (var bookshelf in bookshelfs)
400                 {
401                     await context.Bookshelves.AddAsync(bookshelf);
402                     await context.SaveChangesAsync();
403                 }
404 
405                 foreach (var bookDetail in bookDetails)
406                 {
407                     await context.BooksDetail.AddAsync(bookDetail);
408                     await context.SaveChangesAsync();
409                 }
410 
411                 foreach (var book in books)
412                 {
413                     await context.Books.AddAsync(book);
414                     await context.SaveChangesAsync();
415                 }
416             }
417         }
418     }
View Code

 

在 Configure 方法中调用该数据库初始化方法:

1             BookInitiator.BookInitial(app.ApplicationServices).Wait();

运行后查看数据库:

 

二、图书借阅主页面

首先创建一个视图模型用于确定分页信息:

 1     public class PagingInfo
 2     {
 3         public int TotalItems { get; set; }
 4         public int ItemsPerPage { get; set; }
 5         public int CurrentPage { get; set; }
 6 
 7         public int TotalPages
 8         {
 9             get => (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage);
10         }
11     }

然后创建另一个视图模型用于确定该分页信息以及各分页的书籍:

1     public class BookListViewModel
2     {
3         public IEnumerable<BookDetails> BookDetails { get; set; }
4         public PagingInfo PagingInfo { get; set; }
5     }

创建一个自定义 HtmlHelper 用于在视图中使用 Razor 语法获取分页,在 ASP.NET Core 中 TagBuilder 继承自 IHtmlContent,不能直接对 TagBuilder 进行赋值,需调用 MergeAttribute 方法和 InnerHtml 属性的 AppendHtml 方法编写标签;并且 TagBuilder 没有实现 ToString 方法,只能通过其 WriteTo 方法将内容写到一个 TextWriter 对象中以取出其值:

 1     public static class PagingHelper
 2     {
 3         public static HtmlString PageLinks(this IHtmlHelper html, PagingInfo pagingInfo, Func<int, string> pageUrl)
 4         {
 5             StringWriter writer=new StringWriter();
 6             for (int i = 1; i <= pagingInfo.TotalPages; i++)
 7             {
 8                 TagBuilder tag=new TagBuilder("a");
 9                 tag.MergeAttribute("href",pageUrl(i));
10                 tag.InnerHtml.AppendHtml(i.ToString());
11                 if (i==pagingInfo.CurrentPage)
12                 {
13                     tag.AddCssClass("selected");
14                     tag.AddCssClass("btn-primary");
15                 }
16                 tag.AddCssClass("btn btn-default");
17                 tag.WriteTo(writer,HtmlEncoder.Default);
18             }
19             return new HtmlString(writer.ToString());
20         }
21     }

创建 BookInfo 控制器并确定其中每个分页的书籍数,使用 Session 获取更快地获取书籍信息:

 1     public class BookInfoController : Controller
 2     {
 3         private LendingInfoDbContext _context;
 4         private static int amout = 4;
 5 
 6         public BookInfoController(LendingInfoDbContext context)
 7         {
 8             _context = context;
 9         }
10 
11         public IActionResult Index(string category, int page = 1)
12         {
13             IEnumerable<BookDetails> books = null;
14             if (HttpContext.Session != null)
15             {
16                 books = HttpContext.Session.Get<IEnumerable<BookDetails>>("bookDetails");
17             }
18             if (books == null)
19             {
20                 books = _context.BooksDetail;
21                 HttpContext.Session?.Set<IEnumerable<BookDetails>>("books", books);
22             }
23             BookListViewModel model = new BookListViewModel()
24             {
25                 PagingInfo = new PagingInfo()
26                 {
27                     ItemsPerPage = amout,
28                     TotalItems = books.Count(),
29                     CurrentPage = page,
30                 },
31                 BookDetails = books.OrderBy(b => b.FetchBookNumber).Skip((page - 1) * amout).Take(amout)
32             };            
33             return View(model);
34         }
35 
36         public FileContentResult GetImage(string isbn)
37         {
38             BookDetails target = _context.BooksDetail.FirstOrDefault(b => b.ISBN == isbn);
39             if (target != null)
40             {
41                 return File(target.ImageData, target.ImageMimeType);
42             }
43             return null;
44         }
45     }

视图页面:

24 行利用 BookListViewModel 中 PagingInfo 的 CurrentPage 获取各序号,32 行中使 img 元素的 src 指向 BookInfoController 的 GetImage 方法以获取图片:

 1     @using LibraryDemo.TagHelpers
 2     @model BookListViewModel
 3     @{
 4         ViewData["Title"] = "Index";
 5         int i = 1;
 6     }
 7     <style type="text/css">
 8         tr > td {
 9             padding: 5px;
10             padding-left: 20px;
11         }
12         tr+tr {
13             border-top: thin solid black;
14             padding-top: 10px;
15         }
16     </style>
17 
18     <hr />
19     <table>
20         <tbody>
21         @foreach (var book in Model.BookDetails)
22         {
23             <tr>
24                 <td style="width: 3%">@((@Model.PagingInfo.CurrentPage-1)*4+i++)</td>
25                 <td style="text-align: center; width: 150px; height: 200px;">
26                     @if (book.ImageData == null)
27                     {
28                         <label>No Image</label>
29                     }
30                     else
31                     {
32                         <img class="img-thumbnail pull-left" src="@Url.Action("GetImage", "BookInfo", new {book.ISBN})" />
33                     }   
34                 </td>
35                 <td style="text-align: left;">
36                     <a style="margin-left: 1em;">@book.Name</a>
37                     <div style="margin-left: 2em;margin-top: 5px">
38                         <span>@book.Author</span>
39                         <br />
40                         <span>@book.Press</span>
41                         <p>@book.FetchBookNumber</p>
42                     </div>
43                     <div style="text-indent: 2em">
44                         <p>@book.Description</p>
45                     </div>
46                 </td>
47             </tr>
48         }
49         </tbody>    
50     </table>    
51     <div class="btn-group pull-right">
52         @Html.PageLinks(Model.PagingInfo, x => Url.Action("Index", new { page = x}))
53     </div>

最终结果:

猜你喜欢

转载自www.cnblogs.com/gokoururi/p/10161795.html