I'm a little tired of writing service layer lines, such as:
The following are only examples for readers. Therefore, they may have errors or typos, sorry for that :)
//ViewModel public class EntityIndexFilterPartial { public int? Id { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public IEnumerable<SelectListItem> StatusList { get; set; } public int? StatusID { get; set; } } //Service Layer method //Method parameters are reperesents view model properties public IQueryable<Entity> FilterBy(int? id, DateTime? startDate, DateTime? endDate, int? statusId) { var filter = _db.Entities.AsQueryable(); if (id.HasValue) filter = filter.Where(x => x.Id == id.Value); if (startDate.HasValue) filter = filter.Where(x => x.StartDate >= startDate.Value); if (endDate.HasValue) filter = filter.Where(x => x.EndDate <= endDate.Value); if (statusId.HasValue) filter = filter.Where(x => x.EntityStatus.StatusID == statusId); return filter; }
I am looking for enough for some smart codes. I know about the LINQ dynamic library , and I use it too. But I'm looking for strongly typed filtering . I do not want to write magic lines or some of them.
So basically I found some solutions, but I want to hear some well-written smart codes from this community. Of course, there can be dozens of solutions, but then again, how would you write your strictly typed filtering service level codes. Any ideas ...
Here are some of my solutions:
Solution 1: The same FilterBy method, but the parameters are different, now a list of expressions. Thus, this means that I create a predicate List in the controller and post it here.
public IQueryable<Entity> FilterBy(List<Expression<Func<Entity,bool>>> predicateList) { var filter = _db.Entities.AsQueryable(); foreach (var item in predicateList) { filter = filter.FilterBy(item); } return filter; }
Solution 2: FilterBy using the EntityIndexFilterPartial parameter as a parameter at the application service level (and not for the domain service). I am sure that there are some problems in this design, but I want to hear your opinions.
public IQueryable<Entity> FilterBy(EntityIndexFilterPartial filterPartial) {
Solution 3: I think this is much better than others, but I still think of something simpler and better codes.
//helper class public static class FilterByHelper { public static IQueryable<T> If<T>(this IQueryable<T> filter, bool condition, Expression<Func<T, bool>> predicate) { if (condition) return filter.FilterBy(predicate); return filter; } public static IQueryable<T> FilterBy<T>(this IQueryable<T> filter, Expression<Func<T, bool>> predicate) { return filter.Where(predicate); } } public IQueryable<Entity> FilterBy(int? id, DateTime? startDate, DateTime? endDate, int? statusId) { return _db.Entities .If(id.HasValue, x => x.Id == id.Value) .If(startDate.HasValue, x => x.StartDate >= startDate.Value) .If(endDate.HasValue, x => x.EndDate <= endDate.Value) .If(statusId.HasValue, x => x.EntityStatus.StatusID == statusId); }
I know this has become a bit of a long question, but I hope I clearly ask what I want to ask.
As a quick and easy question, do you know any reasonably designed code to save us from writing the same lines of these filter codes?
Btw, I am not looking for template solutions or huge answers, you can give me an example or say how to find the best way enough.
Of course, if you write the full answer explained, I will be appricated.
Thanks.