c# – 强类型Linq过滤方法

前端之家收集整理的这篇文章主要介绍了c# – 强类型Linq过滤方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有点厌倦了编写这样的服务层代码

下面的代码只是读者的一个例子.所以他们可能有错误或错别字,抱歉:)

  1. //viewmodel
  2. public class EntityIndexFilterPartial
  3. {
  4. public int? Id { get; set; }
  5. public DateTime? StartDate { get; set; }
  6. public DateTime? EndDate { get; set; }
  7. public IEnumerable<SelectListItem> StatusList { get; set; }
  8. public int? StatusID { get; set; }
  9. }
  10.  
  11.  
  12. //Service Layer method
  13. //Method parameters are reperesents view model properties
  14. public IQueryable<Entity> FilterBy(int? id,DateTime? startDate,DateTime? endDate,int? statusId)
  15. {
  16. var filter = _db.Entities.AsQueryable();
  17. if (id.HasValue)
  18. filter = filter.Where(x => x.Id == id.Value);
  19. if (startDate.HasValue)
  20. filter = filter.Where(x => x.StartDate >= startDate.Value);
  21. if (endDate.HasValue)
  22. filter = filter.Where(x => x.EndDate <= endDate.Value);
  23. if (statusId.HasValue)
  24. filter = filter.Where(x => x.EntityStatus.StatusID == statusId);
  25. return filter;
  26. }

搜索了一些智能设计的代码.我知道Dynamic LINQ库,我也使用它.但我正在寻找强类型过滤.
我不想写魔术字符串或某些字符串.

所以基本上我找到了一些解决方案,但我希望从这个社区中听到一些写得很好的智能代码.当然可能有很多解决方案,但是你又如何编写强类型过滤服务层代码.有任何想法吗…

以下是我的一些解决方案:

解决方案1:
相同的FilterBy方法但参数不同,现在采用表达式列表.所以这意味着我在控制器中创建谓词列表并将其发送到此处.

  1. public IQueryable<Entity> FilterBy(List<Expression<Func<Entity,bool>>> predicateList)
  2. {
  3. var filter = _db.Entities.AsQueryable();
  4. foreach (var item in predicateList)
  5. {
  6. filter = filter.FilterBy(item);
  7. }
  8. return filter;
  9. }

解决方案2:
FilterBy方法将EntityIndexFilterPartial作为Application Service层(而非域服务)中的参数.我确信这个设计有一些问题,但我想听听你的意见.

  1. public IQueryable<Entity> FilterBy(EntityIndexFilterPartial filterPartial)
  2. {
  3. //I'm calling the domain service layer FilterBy method such as like in solution 1.
  4. }

解决方案3:
我认为这个比其他人好得多,但我仍在考虑更简单和更好的代码.

  1. //helper class
  2. public static class FilterByHelper
  3. {
  4. public static IQueryable<T> If<T>(this IQueryable<T> filter,bool condition,Expression<Func<T,bool>> predicate)
  5. {
  6. if (condition)
  7. return filter.FilterBy(predicate);
  8. return filter;
  9. }
  10.  
  11. public static IQueryable<T> FilterBy<T>(this IQueryable<T> filter,bool>> predicate)
  12. {
  13. return filter.Where(predicate);
  14. }
  15. }
  16.  
  17.  
  18. public IQueryable<Entity> FilterBy(int? id,int? statusId)
  19. {
  20. return _db.Entities
  21. .If(id.HasValue,x => x.Id == id.Value)
  22. .If(startDate.HasValue,x => x.StartDate >= startDate.Value)
  23. .If(endDate.HasValue,x => x.EndDate <= endDate.Value)
  24. .If(statusId.HasValue,x => x.EntityStatus.StatusID == statusId);
  25. }

我知道这成了一个长长的问题,但我希望我清楚地问我想问什么.

作为一个快速而简单的问题,您是否知道任何设计巧妙的代码,以避免我们编写这些过滤代码的相同行?

顺便说一句,我不是在寻找设计模式解决方案或大答案,你可以给我一些例子或者说如何找到更好的路径就足够了.

当然,如果你写一个完整的解释回复,我会被批评.

谢谢.

解决方法

你试过简单的||条件?
  1. return _db.Entities
  2. .Where(x => id == null || x.Id == id.Value)
  3. .Where(x => startDate == null || x.StartDate >= startDate.Value)
  4. .Where(x => endDate == null || x.EndDate <= endDate.Value)
  5. .Where(x => statusId == null || x => x.EntityStatus.StatusID == statusId);

?我希望在查询优化之后,无操作过滤器相当于根本不添加过滤器.

猜你在找的C#相关文章