I would like to take the ResultSet class shown below and modify it so it can be generic. As you can see, it only accepts Product List but I would like it to take List-OneOfMyModels> or List-T> for the sake of code re-usability in my controllers.
public class ResultSet
{
public List<Product> GetResult(string search, string sortOrder, int start, int length, List<Product> dtResult, List<string> columnFilters)
{
return FilterResult(search, dtResult, columnFilters).SortBy(sortOrder).Skip(start).Take(length).ToList();
}
public int Count(string search, List<Product> dtResult, List<string> columnFilters)
{
return FilterResult(search, dtResult, columnFilters).Count();
}
private IQueryable<Product> FilterResult(string search, List<Product> dtResult, List<string> columnFilters)
{
IQueryable<Product> results = dtResult.AsQueryable();
results = results.Where(p => (search == null || (p.Name != null && p.Name.ToLower().Contains(search.ToLower()) || p.PublicDisplayNo != null && p.PublicDisplayNo.ToLower().Contains(search.ToLower())))
);
return results;
}
}
And in my controller I call the method like so:
public JsonResult DataHandler(DTParameters param)
{
try
{
var dtsource = _context.Products.ToList();
List<String> columnSearch = new List<string>();
foreach (var col in param.Columns)
{
columnSearch.Add(col.Search.Value);
}
List<Product> data = new ResultSet().GetResult(param.Search.Value, param.SortOrder, param.Start, param.Length, dtsource, columnSearch);
int count = new ResultSet().Count(param.Search.Value, dtsource, columnSearch);
DTResult<Product> result = new DTResult<Product>
{
draw = param.Draw,
data = data,
recordsFiltered = count,
recordsTotal = count
};
return Json(result);
}
catch (Exception ex)
{
return Json(new { error = ex.Message });
}
}
This should get you going:
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
public class ResultSet
{
public List<T> GetResult<T>(string search, string sortOrder, int start, int length, List<T> dtResult, List<string> columnFilters) where T : class
{
return FilterResult(search, dtResult, columnFilters).OrderBy(sortOrder).Skip(start).Take(length).ToList();
}
public int Count<T>(string search, List<T> dtResult, List<string> columnFilters) where T : class
{
return FilterResult(search, dtResult, columnFilters).Count();
}
private IQueryable<T> FilterResult<T>(string search, List<T> dtResult, List<string> columnFilters) where T : class
{
IQueryable<T> results = dtResult.AsQueryable();
results = results.Where(p => (search == null || (p.Name != null && p.Name.ToLower().Contains(search.ToLower()) || p.PublicDisplayNo != null && p.PublicDisplayNo.ToLower().Contains(search.ToLower()))));
return results;
}
}
This won't support the cases where you are using properties on the generic type, T, because I have only typed it as a class. You can change the typing following the documentation here . You'll want to type it with a base class or an interface to get things like p.Name
to work.
You would have to make the whole generic like public class ResultSet<T>
or make the methods in the class have generic input and return types like so public List<T> GetResult(params)
.
But this introduces a new problem in the filter result method which uses the actual Products
class to perform search and filter by its properties. Use Reflections in c#, System.Reflection
to look-up class property values of generic types.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.