オブジェクトのリストに適用するために、フィルターのリストを動的に作成する必要がある状況があります。これらのオブジェクトは、フィルタリングする必要のあるすべてのプロパティを含むインターフェイスを実装するものであれば何でもかまいません。
public interface IStuff
{
bool SuitableForSomething { get; set; }
bool SuitableForSomethingElse { get; set; }
}
public class SomeStuff : IStuff
{
...
}
public class SomeOtherStuff : IStuff
{
...
}
私はそのように定義された基準のリストを持っています...
public List<Expression<Func<IStuff, bool>>> Criteria { get; private set; }
そしてそのような基準を追加します...
Criteria.Add(x => x.SuitableForSomething);
Criteria.Add(x => x.SuitableForSomethingElse);
次に、次のように条件をクエリに適用します...
var stuff= _stuffCache
.GetAll()
.AsQueryable()
.ApplyCriteria(Criteria);
次の拡張メソッドを使用します...
public static IQueryable<T> ApplyCriteria<T>(this IQueryable<T> stuff, List<Expression<Func<IStuff, bool>>> criteria)
where T : IStuff
{
foreach (var expression in criteria)
{
stuff = Queryable.Where(stuff, expression);
}
return stuff;
}
コンパイラは私に言っています...
cannot convert from
'System.Linq.Expressions.Expression<System.Func<IStuff,bool>>'
to
'System.Linq.Expressions.Expression<System.Func<T,int,bool>>'
IDEのエラーの下にある赤い線にカーソルを合わせると、その間のメソッドを解決できないと表示されます。
IQueryable<IStuff> Where<IStuff>(this IQueryable<IStuff>, Expression<Func<IStuff, bool>>) in class Queryable
and
IQueryable<T> Where<T>(this IQueryable<T>, Expression<Func<T,int,bool>>) in class Queryable
式をにキャストしようとするとExpression<Func<T, bool>>
、TはIStuffインターフェイスを実装するように制約されているため、これは機能するはずです。私は得る
Cannot cast expression of type 'Expression<Func<IStuff, bool>>' to type 'Expression<Func<T, bool>>'
編集Raphaëlの答えの
おかげで、私は拡張メソッドを修正し、最終的に私が持っていた本当の問題を見つけました。それは私がコードを呼び出していたときのキャストの問題でした。.Cast<SomeStuff>()
呼び出しの後にを追加することで簡単に修正できApplyCriteria
ます。
前
var stuff= _stuffCache
.GetAll()
.AsQueryable()
.ApplyCriteria(Criteria);
後
var stuff= _stuffCache
.GetAll()
.AsQueryable()
.ApplyCriteria(Criteria)
.Cast<SomeStuff>();