我有点累的像这样的服务层的代码编写行:强类型的LINQ滤波方法
下面的代码只是为了读者的例子。因此,他们可能有错误或错别字,不好意思吧:)
//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;
}
我寻找足够漂亮了一些聪明的设计代码。我知道动态LINQ库,我使用它。但是我正在寻找强类型的过滤。 我不想写魔术字符串或某种他们。
所以基本上我找到了一些解决方案,但我想从这个社会听到一些写得好聪明的代码。当然,可能有几十种解决方案,但是又如何编写强类型过滤服务层代码。任何想法...
这里有一些我的解决方案:
解决方案1: 同FilterBy方法,但参数是不同的,现在正在表达式列表。所以这意味着我在控制器中创建predicateList并将它发送到这里。
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;
}
解决方案2: FilterBy方法服用EntityIndexFilterPartial如在应用服务层(未域服务)参数。我确信这个设计有一些问题,但我想听听你的意见。
public IQueryable<Entity> FilterBy(EntityIndexFilterPartial filterPartial)
{
//I'm calling the domain service layer FilterBy method such as like in solution 1.
}
解决方案3: 我觉得这个要比别人更好,但我仍然在想的东西更简单,更好的代码。
//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);
}
我知道这成为一个有点长的问题,但我希望我清楚地问我想问什么。
作为一个快速和简单的问题,你知道从写这些过滤代码相同的路线为我们节省任何设计巧妙的代码?
顺便说一句,我不是寻找设计模式解决方案或巨大的答案,你可以给我一些例子或说如何找到更好的路径就够了。
当然,如果你写一个完整的解释回应,我会appricated。
谢谢。
+1,但恐怕OP不会喜欢这个codez要么;) – Icarus
+1这是很好的把戏。您能否提出一个更好的解决方案来提供服务层方法参数我关于摆脱这些参数的问题的一部分。谢谢:) –
@YusufUzun:对不起,我真的不明白你的意思,我很害怕。你如何通过没有任何参数的过滤器? –