这一次似乎是矫枉过正,我(但我想这是出现在评论多态性),但无论如何, ,还有它是:
我们先从一个接口:
public interface IQueryFilter
{
IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria);
}
然后实现共同财产:
public abstract class AQueryFilter<T> : IQueryFilter
{
public AQueryFilter(Func<SearchCriteria, T> criteria)
{
Criteria = criteria;
}
protected Func<SearchCriteria, T> Criteria { get; }
public abstract IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria);
}
最后,所有具体的东西:
public class WhereEventStatusQueryFilter : AQueryFilter<bool>
{
private EventStatus _toTest;
public WhereEventStatusQueryFilter(Func<SearchCriteria, bool> criteria, EventStatus toTest)
: base(criteria)
{
_toTest = toTest;
}
public override IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria)
{
return (Criteria(searchCriteria) ? query : query.Where(x => x.EventStatusId != _toTest));
}
}
public class SearchQueryFilter : AQueryFilter<object>
{
Func<Whatever, object> _searchFor;
public SearchQueryFilter(Func<SearchCriteria, object> criteria, Func<Whatever, object> searchFor)
: base(criteria)
{
_searchFor = searchFor;
}
public override IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria)
{
return (Criteria(searchCriteria) == null ? query : query.Search(x => _searchFor(x), Criteria(searchCriteria)));
}
}
public class WhereEqualQueryFilter : AQueryFilter<object>
{
Func<Whatever, object> _searchFor;
public WhereEqualQueryFilter(Func<SearchCriteria, object> criteria, Func<Whatever, object> searchFor)
: base(criteria)
{
_searchFor = searchFor;
}
public override IQueryable<Whatever> Filter(IQueryable<Whatever> query, SearchCriteria searchCriteria)
{
return (Criteria(searchCriteria) == null ? query : query.Where(x => _searchFor(x) == Criteria(searchCriteria)));
}
}
用法:
var filters = new IQueryFilter[]
{
new WhereEventStatusQueryFilter(x => x.PendingEvent, EventStatus.Pending),
new WhereEventStatusQueryFilter(x => x.VerifiedEvent, EventStatus.Verified),
new SearchQueryFilter(x => x.EventReference, x => x.EventReference),
new WhereEqualQueryFilter(x => x.RemittedId, x => x.Trade.RemittedId),
...
};
foreach (var filter in filters)
query = filter.Filter(query, searchCriteria);
但这种方法隐藏了很多的逻辑。如果有人想添加一些内容,他必须阅读所有以前的过滤器类,以了解是否已有可以完成工作或者必须编写另一个过滤器的类。
这是一个很好的问题:http://codereview.stackexchange.com –
对象编程与否,这是构建动态过滤器的正确方法。您可以随时将大方法的某些部分提取到自己的方法中,就像任何常规方法重构一样,“Where”和“IQueryable”没有什么共同之处。 –
如果你想关注的行数,然后从'if'条件中删除'{}'括号,你会减少两条线,每个条件:) –