6

オブジェクトのリストに適用するために、フィルターのリストを動的に作成する必要がある状況があります。これらのオブジェクトは、フィルタリングする必要のあるすべてのプロパティを含むインターフェイスを実装するものであれば何でもかまいません。

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>();
4

1 に答える 1

7

2番目のパラメータータイプをList<Expression<Func<T,bool>>>(IStuffではなくT)に変更します

public static IQueryable<T> ApplyCriteria<T>(this IQueryable<T> stuff, List<Expression<Func<T, bool>>> criteria) 
    where T : IStuff
{
    foreach (var expression in criteria)
    {
        stuff = Queryable.Where(stuff, expression);
        //or stuff = stuff.Where(expression), as Where is an Extension method;
    }
    return stuff;
}

そしてあなたのメソッドは(thx resharper)、に書き直されることができます

public static IQueryable<T> ApplyCriteria<T>(this IQueryable<T> stuff, List<Expression<Func<T, bool>>> criteria)
            where T : IStuff
        {
            return criteria.Aggregate(stuff, (current, expression) => current.Where(expression));
        }
于 2012-06-14T11:29:37.593 に答える