Skip to content

Commit b73cbbe

Browse files
Improved LINQ Queries, Improved LinqExtensions and Simplified Razor View
1 parent 09c4564 commit b73cbbe

File tree

5 files changed

+81
-69
lines changed

5 files changed

+81
-69
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
\.vs/
33

4-
jQueryDatatableServerSideNetCore22/bin/
4+
src/jQueryDatatableServerSideNetCore22/bin/
55

6-
jQueryDatatableServerSideNetCore22/obj/
6+
src/jQueryDatatableServerSideNetCore22/obj/

src/jQueryDatatableServerSideNetCore22/Controllers/TestRegistersController.cs

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,42 +29,24 @@ public async Task<IActionResult> Index()
2929
}
3030

3131
[HttpPost]
32-
public async Task<IActionResult> LoadTable([FromBody]DTParameters dtParameters)
32+
public async Task<IActionResult> LoadTable([FromBody]DtParameters dtParameters)
3333
{
3434
var searchBy = dtParameters.Search?.Value;
3535

36-
var orderCriteria = string.Empty;
37-
var orderAscendingDirection = true;
36+
// if we have an empty search then just order the results by Id ascending
37+
var orderCriteria = "Id";
38+
var orderAscendingDirection = DtOrderDir.Asc;
3839

3940
if (dtParameters.Order != null)
4041
{
4142
// in this example we just default sort on the 1st column
4243
orderCriteria = dtParameters.Columns[dtParameters.Order[0].Column].Data;
43-
orderAscendingDirection = dtParameters.Order[0].Dir.ToString().ToLower() == "asc";
44-
}
45-
else
46-
{
47-
// if we have an empty search then just order the results by Id ascending
48-
orderCriteria = "Id";
49-
orderAscendingDirection = true;
50-
}
51-
52-
var result = await _context.TestRegisters.ToListAsync();
53-
54-
if (!string.IsNullOrEmpty(searchBy))
55-
{
56-
result = result.Where(r => r.Name != null && r.Name.ToUpper().Contains(searchBy.ToUpper()) ||
57-
r.FirstSurname != null && r.FirstSurname.ToUpper().Contains(searchBy.ToUpper()) ||
58-
r.SecondSurname != null && r.SecondSurname.ToUpper().Contains(searchBy.ToUpper()) ||
59-
r.Street != null && r.Street.ToUpper().Contains(searchBy.ToUpper()) ||
60-
r.Phone != null && r.Phone.ToUpper().Contains(searchBy.ToUpper()) ||
61-
r.ZipCode != null && r.ZipCode.ToUpper().Contains(searchBy.ToUpper()) ||
62-
r.Country != null && r.Country.ToUpper().Contains(searchBy.ToUpper()) ||
63-
r.Notes != null && r.Notes.ToUpper().Contains(searchBy.ToUpper()))
64-
.ToList();
44+
orderAscendingDirection = dtParameters.Order[0].Dir.ToString().ToLower() == "asc" ? DtOrderDir.Asc : DtOrderDir.Desc;
6545
}
6646

67-
result = orderAscendingDirection ? result.AsQueryable().OrderByDynamic(orderCriteria, LinqExtensions.Order.Asc).ToList() : result.AsQueryable().OrderByDynamic(orderCriteria, LinqExtensions.Order.Desc).ToList();
47+
var result = _context.TestRegisters
48+
.WhereDynamic(searchBy)
49+
.OrderByDynamic(orderCriteria,orderAscendingDirection);
6850

6951
// now just get the count of items (without the skip and take) - eg how many could be returned with filtering
7052
var filteredResultsCount = result.Count();
Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,54 @@
11
using System;
22
using System.Linq;
33
using System.Linq.Expressions;
4+
using jQueryDatatableServerSideNetCore22.Models.AuxiliaryModels;
45

56
namespace jQueryDatatableServerSideNetCore22.Extensions
67
{
78
public static class LinqExtensions
89
{
9-
public enum Order
10-
{
11-
Asc,
12-
Desc
13-
}
14-
1510
public static IQueryable<T> OrderByDynamic<T>(
1611
this IQueryable<T> query,
1712
string orderByMember,
18-
Order direction)
13+
DtOrderDir ascendingDirection)
14+
{
15+
var param = Expression.Parameter(typeof(T), "c");
16+
17+
var body = orderByMember.Split('.').Aggregate<string, Expression>(param, Expression.PropertyOrField);
18+
19+
var queryable = ascendingDirection == DtOrderDir.Asc ?
20+
(IOrderedQueryable<T>)Queryable.OrderBy(query.AsQueryable(), (dynamic)Expression.Lambda(body, param)) :
21+
(IOrderedQueryable<T>)Queryable.OrderByDescending(query.AsQueryable(), (dynamic)Expression.Lambda(body, param));
22+
23+
return queryable;
24+
}
25+
26+
public static IQueryable<T> WhereDynamic<T>(
27+
this IQueryable<T> sourceList, string query)
1928
{
20-
var queryElementTypeParam = Expression.Parameter(typeof(T));
2129

22-
var memberAccess = Expression.PropertyOrField(queryElementTypeParam, orderByMember);
30+
if (string.IsNullOrEmpty(query))
31+
{
32+
return sourceList;
33+
}
34+
35+
try
36+
{
2337

24-
var keySelector = Expression.Lambda(memberAccess, queryElementTypeParam);
38+
var properties = typeof(T).GetProperties()
39+
.Where(x => x.CanRead && x.CanWrite && !x.GetGetMethod().IsVirtual);
2540

26-
var orderBy = Expression.Call(
27-
typeof(Queryable),
28-
direction == Order.Asc ? "OrderBy" : "OrderByDescending",
29-
new Type[] { typeof(T), memberAccess.Type },
30-
query.Expression,
31-
Expression.Quote(keySelector));
41+
//Expression
42+
sourceList = sourceList.Where(c =>
43+
properties.Any(p => p.GetValue(c).ToString()
44+
.Contains(query, StringComparison.InvariantCultureIgnoreCase)));
45+
}
46+
catch (Exception e)
47+
{
48+
Console.WriteLine(e);
49+
}
3250

33-
return query.Provider.CreateQuery<T>(orderBy);
51+
return sourceList;
3452
}
3553
}
3654
}

src/jQueryDatatableServerSideNetCore22/Models/AuxiliaryModels/DatatableModels.cs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,75 @@
11
using System.Collections.Generic;
2+
using Newtonsoft.Json;
23

34
namespace jQueryDatatableServerSideNetCore22.Models.AuxiliaryModels
45
{
6+
///This view model class has been referred from example created by Marien Monnier at Soft.it. All credits to Marien for this class
7+
58
/// <summary>
69
/// A full result, as understood by jQuery DataTables.
710
/// </summary>
811
/// <typeparam name="T">The data type of each row.</typeparam>
9-
public class DTResult<T>
12+
public class DtResult<T>
1013
{
1114
/// <summary>
1215
/// The draw counter that this object is a response to - from the draw parameter sent as part of the data request.
1316
/// Note that it is strongly recommended for security reasons that you cast this parameter to an integer, rather than simply echoing back to the client what it sent in the draw parameter, in order to prevent Cross Site Scripting (XSS) attacks.
1417
/// </summary>
15-
public int draw { get; set; }
18+
[JsonProperty("draw")]
19+
public int Draw { get; set; }
1620

1721
/// <summary>
1822
/// Total records, before filtering (i.e. the total number of records in the database)
1923
/// </summary>
20-
public int recordsTotal { get; set; }
24+
[JsonProperty("recordsTotal")]
25+
public int RecordsTotal { get; set; }
2126

2227
/// <summary>
2328
/// Total records, after filtering (i.e. the total number of records after filtering has been applied - not just the number of records being returned for this page of data).
2429
/// </summary>
25-
public int recordsFiltered { get; set; }
30+
[JsonProperty("recordsFiltered")]
31+
public int RecordsFiltered { get; set; }
2632

2733
/// <summary>
2834
/// The data to be displayed in the table.
2935
/// This is an array of data source objects, one for each row, which will be used by DataTables.
3036
/// Note that this parameter's name can be changed using the ajaxDT option's dataSrc property.
3137
/// </summary>
32-
public IEnumerable<T> data { get; set; }
38+
[JsonProperty("data")]
39+
public IEnumerable<T> Data { get; set; }
40+
41+
public string PartialView { get; set; }
3342
}
3443

3544
/// <summary>
3645
/// The additional columns that you can send to jQuery DataTables for automatic processing.
3746
/// </summary>
38-
public abstract class DTRow
47+
public abstract class DtRow
3948
{
4049
/// <summary>
4150
/// Set the ID property of the dt-tag tr node to this value
4251
/// </summary>
43-
public virtual string DT_RowId => null;
52+
[JsonProperty("DT_RowId")]
53+
public virtual string DtRowId => null;
4454

4555
/// <summary>
4656
/// Add this class to the dt-tag tr node
4757
/// </summary>
48-
public virtual string DT_RowClass => null;
58+
[JsonProperty("DT_RowClass")]
59+
public virtual string DtRowClass => null;
4960

5061
/// <summary>
5162
/// Add this data property to the row's dt-tag tr node allowing abstract data to be added to the node, using the HTML5 data-* attributes.
5263
/// This uses the jQuery data() method to set the data, which can also then be used for later retrieval (for example on a click event).
5364
/// </summary>
54-
public virtual object DT_RowData => null;
65+
[JsonProperty("DT_RowData")]
66+
public virtual object DtRowData => null;
5567
}
5668

5769
/// <summary>
5870
/// The parameters sent by jQuery DataTables in AJAX queries.
5971
/// </summary>
60-
public class DTParameters
72+
public class DtParameters
6173
{
6274
/// <summary>
6375
/// Draw counter.
@@ -69,12 +81,12 @@ public class DTParameters
6981
/// <summary>
7082
/// An array defining all columns in the table.
7183
/// </summary>
72-
public DTColumn[] Columns { get; set; }
84+
public DtColumn[] Columns { get; set; }
7385

7486
/// <summary>
7587
/// An array defining how many columns are being ordering upon - i.e. if the array length is 1, then a single column sort is being performed, otherwise a multi-column sort is being performed.
7688
/// </summary>
77-
public DTOrder[] Order { get; set; }
89+
public DtOrder[] Order { get; set; }
7890

7991
/// <summary>
8092
/// Paging first record indicator.
@@ -92,14 +104,14 @@ public class DTParameters
92104
/// <summary>
93105
/// Global search value. To be applied to all columns which have searchable as true.
94106
/// </summary>
95-
public DTSearch Search { get; set; }
107+
public DtSearch Search { get; set; }
96108

97109
/// <summary>
98110
/// Custom column that is used to further sort on the first Order column.
99111
/// </summary>
100112
public string SortOrder => Columns != null && Order != null && Order.Length > 0
101113
? (Columns[Order[0].Column].Data +
102-
(Order[0].Dir == DTOrderDir.DESC ? " " + Order[0].Dir : string.Empty))
114+
(Order[0].Dir == DtOrderDir.Desc ? " " + Order[0].Dir : string.Empty))
103115
: null;
104116

105117
/// <summary>
@@ -112,7 +124,7 @@ public class DTParameters
112124
/// <summary>
113125
/// A jQuery DataTables column.
114126
/// </summary>
115-
public class DTColumn
127+
public class DtColumn
116128
{
117129
/// <summary>
118130
/// Column's data source, as defined by columns.data.
@@ -137,13 +149,13 @@ public class DTColumn
137149
/// <summary>
138150
/// Specific search value.
139151
/// </summary>
140-
public DTSearch Search { get; set; }
152+
public DtSearch Search { get; set; }
141153
}
142154

143155
/// <summary>
144156
/// An order, as sent by jQuery DataTables when doing AJAX queries.
145157
/// </summary>
146-
public class DTOrder
158+
public class DtOrder
147159
{
148160
/// <summary>
149161
/// Column to which ordering should be applied.
@@ -155,22 +167,22 @@ public class DTOrder
155167
/// Ordering direction for this column.
156168
/// It will be dt-string asc or dt-string desc to indicate ascending ordering or descending ordering, respectively.
157169
/// </summary>
158-
public DTOrderDir Dir { get; set; }
170+
public DtOrderDir Dir { get; set; }
159171
}
160172

161173
/// <summary>
162174
/// Sort orders of jQuery DataTables.
163175
/// </summary>
164-
public enum DTOrderDir
176+
public enum DtOrderDir
165177
{
166-
ASC,
167-
DESC
178+
Asc,
179+
Desc
168180
}
169181

170182
/// <summary>
171183
/// A search, as sent by jQuery DataTables when doing AJAX queries.
172184
/// </summary>
173-
public class DTSearch
185+
public class DtSearch
174186
{
175187
/// <summary>
176188
/// Global search value. To be applied to all columns which have searchable as true.

src/jQueryDatatableServerSideNetCore22/Views/TestRegisters/Index.cshtml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
</th>
4343
<th></th>
4444
</tr>
45-
<tr>
45+
@*<tr>
4646
<th></th>
4747
<th></th>
4848
<th></th>
@@ -54,7 +54,7 @@
5454
<th></th>
5555
<th></th>
5656
<th></th>
57-
</tr>
57+
</tr>*@
5858
</thead>
5959
</table>
6060
</div>

0 commit comments

Comments
 (0)