Skip to content

Commit ab14bc2

Browse files
committed
Index
1 parent a0cfbec commit ab14bc2

File tree

5 files changed

+153
-65
lines changed

5 files changed

+153
-65
lines changed

ContosoUniversity/Features/MappingExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq;
33
using System.Threading.Tasks;
44
using AutoMapper;
5+
using AutoMapper.QueryableExtensions;
56
using Microsoft.EntityFrameworkCore;
67

78
namespace ContosoUniversity.Features
@@ -34,6 +35,9 @@ public QueryableExpression(IQueryable<TSource> items)
3435
public async Task<IList<TDestination>> ToListAsync<TDestination>()
3536
=> (await _items.ToListAsync()).Select(src => Mapper.Map<TSource, TDestination>(src)).ToList();
3637

38+
public Task<PaginatedList<TDestination>> ToPaginatedListAsync<TDestination>(int pageNumber, int pageSize)
39+
=> PaginatedList<TDestination>.CreateAsync(_items.ProjectTo<TDestination>(), pageNumber, pageSize);
40+
3741
public async Task<TDestination> SingleOrDefaultAsync<TDestination>()
3842
=> Mapper.Map<TSource, TDestination>(await _items.SingleOrDefaultAsync());
3943
}
@@ -48,5 +52,6 @@ public interface IQueryableExpression
4852
{
4953
Task<IList<TDestination>> ToListAsync<TDestination>();
5054
Task<TDestination> SingleOrDefaultAsync<TDestination>();
55+
Task<PaginatedList<TDestination>> ToPaginatedListAsync<TDestination>(int pageNumber, int pageSize);
5156
}
5257
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using ContosoUniversity.Data;
6+
using ContosoUniversity.Models;
7+
using MediatR;
8+
9+
namespace ContosoUniversity.Features.Students
10+
{
11+
public class Index
12+
{
13+
public class Query : IRequest<Result>
14+
{
15+
public string SortOrder { get; set; }
16+
public string CurrentFilter { get; set; }
17+
public string SearchString { get; set; }
18+
public int? Page { get; set; }
19+
}
20+
21+
public class Result
22+
{
23+
public string CurrentSort { get; set; }
24+
public string NameSortParm { get; set; }
25+
public string DateSortParm { get; set; }
26+
public string CurrentFilter { get; set; }
27+
public string SearchString { get; set; }
28+
29+
public PaginatedList<Model> Results { get; set; }
30+
}
31+
32+
public class Model
33+
{
34+
public int ID { get; set; }
35+
[Display(Name = "First Name")]
36+
public string FirstMidName { get; set; }
37+
public string LastName { get; set; }
38+
public DateTime EnrollmentDate { get; set; }
39+
}
40+
41+
public class QueryHandler : IAsyncRequestHandler<Query, Result>
42+
{
43+
private readonly SchoolContext _db;
44+
45+
public QueryHandler(SchoolContext db)
46+
{
47+
_db = db;
48+
}
49+
50+
public async Task<Result> Handle(Query message)
51+
{
52+
var model = new Result
53+
{
54+
CurrentSort = message.SortOrder,
55+
NameSortParm = String.IsNullOrEmpty(message.SortOrder) ? "name_desc" : "",
56+
DateSortParm = message.SortOrder == "Date" ? "date_desc" : "Date",
57+
};
58+
59+
if (message.SearchString != null)
60+
{
61+
message.Page = 1;
62+
}
63+
else
64+
{
65+
message.SearchString = message.CurrentFilter;
66+
}
67+
68+
model.CurrentFilter = message.SearchString;
69+
model.SearchString = message.SearchString;
70+
71+
IQueryable<Student> students = _db.Students;
72+
if (!String.IsNullOrEmpty(message.SearchString))
73+
{
74+
students = students.Where(s => s.LastName.Contains(message.SearchString)
75+
|| s.FirstMidName.Contains(message.SearchString));
76+
}
77+
switch (message.SortOrder)
78+
{
79+
case "name_desc":
80+
students = students.OrderByDescending(s => s.LastName);
81+
break;
82+
case "Date":
83+
students = students.OrderBy(s => s.EnrollmentDate);
84+
break;
85+
case "date_desc":
86+
students = students.OrderByDescending(s => s.EnrollmentDate);
87+
break;
88+
default: // Name ascending
89+
students = students.OrderBy(s => s.LastName);
90+
break;
91+
}
92+
93+
int pageSize = 3;
94+
int pageNumber = (message.Page ?? 1);
95+
model.Results = await students.Map().ToPaginatedListAsync<Model>(pageNumber, pageSize);
96+
97+
return model;
98+
}
99+
}
100+
}
101+
}
Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model PaginatedList<ContosoUniversity.Models.Student>
1+
@model ContosoUniversity.Features.Students.Index.Result
22

33
@{
44
ViewData["Title"] = "Index";
@@ -13,7 +13,7 @@
1313
<form asp-action="Index" method="get">
1414
<div class="form-actions no-color">
1515
<p>
16-
Find by name: <input type="text" name="SearchString" value="@ViewData["currentFilter"]" />
16+
Find by name: <input type="text" name="SearchString" value="@Model.CurrentFilter" />
1717
<input type="submit" value="Search" class="btn btn-default" /> |
1818
<a asp-action="Index">Back to Full List</a>
1919
</p>
@@ -24,56 +24,58 @@
2424
<thead>
2525
<tr>
2626
<th>
27-
<a asp-action="Index" asp-route-sortOrder="@ViewData["NameSortParm"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">Last Name</a>
27+
<a asp-action="Index" asp-route-sortOrder="@Model.NameSortParm" asp-route-currentFilter="@Model.CurrentFilter">Last Name</a>
2828
</th>
2929
<th>
3030
First Name
3131
</th>
3232
<th>
33-
<a asp-action="Index" asp-route-sortOrder="@ViewData["DateSortParm"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">Enrollment Date</a>
33+
<a asp-action="Index" asp-route-sortOrder="@Model.DateSortParm" asp-route-currentFilter="@Model.CurrentFilter">Enrollment Date</a>
3434
</th>
3535
<th></th>
3636
</tr>
3737
</thead>
3838
<tbody>
39-
@foreach (var item in Model)
39+
@{ int i = 0; }
40+
@foreach (var item in Model.Results)
4041
{
4142
<tr>
4243
<td>
43-
@Html.DisplayFor(modelItem => item.LastName)
44+
<display-tag for="Results[i].LastName"/>
4445
</td>
4546
<td>
46-
@Html.DisplayFor(modelItem => item.FirstMidName)
47+
<display-tag for="Results[i].FirstMidName" />
4748
</td>
4849
<td>
49-
@Html.DisplayFor(modelItem => item.EnrollmentDate)
50+
<display-tag for="Results[i].EnrollmentDate" />
5051
</td>
5152
<td>
52-
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
53-
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
54-
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
53+
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
54+
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
55+
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
5556
</td>
5657
</tr>
58+
i++;
5759
}
5860
</tbody>
5961
</table>
6062

6163
@{
62-
var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
63-
var nextDisabled = !Model.HasNextPage ? "disabled" : "";
64+
var prevDisabled = !Model.Results.HasPreviousPage ? "disabled" : "";
65+
var nextDisabled = !Model.Results.HasNextPage ? "disabled" : "";
6466
}
6567

6668
<a asp-action="Index"
67-
asp-route-sortOrder="@ViewData["CurrentSort"]"
68-
asp-route-page="@(Model.PageIndex - 1)"
69-
asp-route-currentFilter="@ViewData["CurrentFilter"]"
69+
asp-route-sortOrder="@Model.CurrentSort"
70+
asp-route-page="@(Model.Results.PageIndex - 1)"
71+
asp-route-currentFilter="@Model.CurrentFilter"
7072
class="btn btn-default @prevDisabled">
7173
Previous
7274
</a>
7375
<a asp-action="Index"
74-
asp-route-sortOrder="@ViewData["CurrentSort"]"
75-
asp-route-page="@(Model.PageIndex + 1)"
76-
asp-route-currentFilter="@ViewData["CurrentFilter"]"
76+
asp-route-sortOrder="@Model.CurrentSort"
77+
asp-route-page="@(Model.Results.PageIndex + 1)"
78+
asp-route-currentFilter="@Model.CurrentFilter"
7779
class="btn btn-default @nextDisabled">
7880
Next
7981
</a>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using AutoMapper;
2+
using ContosoUniversity.Models;
3+
4+
namespace ContosoUniversity.Features.Students
5+
{
6+
public class MappingProfile : Profile
7+
{
8+
public MappingProfile()
9+
{
10+
CreateMap<Student, Index.Model>();
11+
//CreateMap<Student, Details.Model>();
12+
//CreateMap<Enrollment, Details.Model.Enrollment>();
13+
//CreateMap<Create.Command, Student>(MemberList.Source);
14+
//CreateMap<Student, Edit.Command>().ReverseMap();
15+
//CreateMap<Student, Delete.Command>().ReverseMap();
16+
}
17+
}
18+
}

ContosoUniversity/Features/Students/StudentsController.cs

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading.Tasks;
44
using ContosoUniversity.Data;
55
using ContosoUniversity.Models;
6+
using MediatR;
67
using Microsoft.AspNetCore.Mvc;
78
using Microsoft.EntityFrameworkCore;
89

@@ -11,60 +12,21 @@ namespace ContosoUniversity.Features.Students
1112
public class StudentsController : Controller
1213
{
1314
private readonly SchoolContext _context;
15+
private readonly IMediator _mediator;
1416

15-
public StudentsController(SchoolContext context)
17+
public StudentsController(SchoolContext context, IMediator mediator)
1618
{
1719
_context = context;
20+
_mediator = mediator;
1821
}
1922

20-
// GET: Students
21-
public async Task<IActionResult> Index(
22-
string sortOrder,
23-
string currentFilter,
24-
string searchString,
25-
int? page)
23+
public async Task<ViewResult> Index(Index.Query query)
2624
{
27-
ViewData["CurrentSort"] = sortOrder;
28-
ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
29-
ViewData["DateSortParm"] = sortOrder == "Date" ? "date_desc" : "Date";
25+
var model = await _mediator.Send(query);
3026

31-
if (searchString != null)
32-
{
33-
page = 1;
34-
}
35-
else
36-
{
37-
searchString = currentFilter;
38-
}
39-
40-
ViewData["CurrentFilter"] = searchString;
41-
42-
var students = from s in _context.Students
43-
select s;
44-
if (!String.IsNullOrEmpty(searchString))
45-
{
46-
students = students.Where(s => s.LastName.Contains(searchString)
47-
|| s.FirstMidName.Contains(searchString));
48-
}
49-
switch (sortOrder)
50-
{
51-
case "name_desc":
52-
students = students.OrderByDescending(s => s.LastName);
53-
break;
54-
case "Date":
55-
students = students.OrderBy(s => s.EnrollmentDate);
56-
break;
57-
case "date_desc":
58-
students = students.OrderByDescending(s => s.EnrollmentDate);
59-
break;
60-
default:
61-
students = students.OrderBy(s => s.LastName);
62-
break;
63-
}
64-
65-
int pageSize = 3;
66-
return View(await PaginatedList<Student>.CreateAsync(students.AsNoTracking(), page ?? 1, pageSize));
27+
return View(model);
6728
}
29+
6830
// GET: Students/Details/5
6931
public async Task<IActionResult> Details(int? id)
7032
{

0 commit comments

Comments
 (0)