2016-08-29 4 views
4

での句Iは、エンティティフレームワークを使用していますし、私のようなダイナミックな表現を作成する必要があります。ダイナミックはどこラムダ

var sel = Expression.Lambda<Func<TEntity, bool>>(propertyAccess, parameter); 
var compiledSel = sel.Compile(); 
// sel = x.Name 
// filter.Value = "John" 
Repository.GetData.Where(item => compiledSel(item) != null && compiledSel(item).ToLower().StartsWith(filter.Value.ToString().ToLower())) 

IQueriableと上記の作品を、私はそれは、エンティティフレームワークと連携する必要があります。私は、例えばへ

item => compiledSel(item) != null && compiledSel(item).ToLower().StartsWith(filter.Value.ToString().ToLower()) 

を解析する必要があることを意味

x => x.Name != null && x.Name.StartsWith("John") 

私は動的にフィルタリングできるようにしたい複数のエンティティを持っているので、私はこれをやっている理由があります。

提案がありますか?

編集:

EFに対してクエリ自体がここで実行されます。

private IList<TEntity> GetCollection(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, object>>[] includes) 
{ 
    return DbSet 
    .Where(where) 
    .ApplyIncludes(includes) 
    .ToList(); 
} 

私は今節はParam_0 => (((Invoke(value(....であると私はThe LINQ expression node type 'Invoke' is not supported in LINQ to Entities.エラー

+0

方法エンティティ?例えば'class MyEntity:INameable'を' string Name'プロパティに設定し、 'Func 'を動的に使うことができます –

+0

'propertyAccess'変数には何が入っていますか? Stringプロパティアクセサ?だから、 'sel'は、例のように、' Expression > 'ではなく、' Expression > 'ですか? –

+0

INamebleを追加する際の問題は、異なるエンティティが多数あることです。したがって、「x.Name」は単なる例に過ぎません。 – h3li0s

答えて

3

まずオフpropertyAccessは、文字列プロパティへのアクセサであれば、以下の

var sel = Expression.Lambda<Func<TEntity, bool>>(propertyAccess, parameter); 

var sel = Expression.Lambda<Func<TEntity, string>>(propertyAccess, parameter); 

第二に、CompileはEF表現の内部では動作しませんする必要があります。 Expressionクラスのメソッドを使用して手動で述語式全体を構築することはできますが、それは比較的難しいです。私はあなたがこのように「プロトタイプ」という表現は、簡単なパラメータの代用品を使用することであることを示唆している可能性があり:

var selector = Expression.Lambda<Func<TEntity, string>>(propertyAccess, parameter); 

var value = filter.Value.ToString().ToLower(); 

Expression<Func<string, bool>> prototype = 
    item => item != null && item.ToLower().StartsWith(value); 

var predicate = Expression.Lambda<Func<T, bool>>(
    prototype.Body.ReplaceParameter(prototype.Parameters[0], selector.Body), 
    selector.Parameters[0]); 

ここでは、使用されるヘルパーメソッドのコードです:あなたへのインタフェースを追加する方法について

public static class ExpressionUtils 
{ 
    public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target) 
    { 
     return new ParameterReplacer { Source = source, Target = target }.Visit(expression); 
    } 

    class ParameterReplacer : ExpressionVisitor 
    { 
     public ParameterExpression Source; 
     public Expression Target; 
     protected override Expression VisitParameter(ParameterExpression node) 
     { 
      return node == Source ? Target : base.VisitParameter(node); 
     } 
    } 
} 
+1

ありがとう!これは私の問題を解決する! – h3li0s

関連する問題