この1つは私にはやり過ぎのようです(私はそれがコメントで表示された多型だと思う)、とにかく、そこにそれがある:
我々はインターフェイスを起動します。
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 –
オブジェクトプログラミングかどうか、これは動的フィルタを構築する正しい方法です。通常のメソッドリファクタリングの場合と同様に、Bigメソッドの一部を独自のメソッドに取り出すことができますが、WhereとIQueryableは共通していません。 –
行数が問題になる場合は、{if}条件から '{}'大括弧を削除すると、条件ごとに2行減ります:) –