2017-05-06 13 views
4

既に存在するラムダツリー式 を使用して列をさらに取得するにはどうすればよいですか?これはEntity Frameworkと連動して動作します。Lambda式に追加してEntity Frameworkを使用する

Expression<Func<DivisionTeam, DirectorTeamModel>> columns= (d) => new DirectorTeamModel 
{ 
    Id = d.Id, 
    TeamId = d.Team.Id 
}; 

if (criteria.Template == ExportTemplate.Import || criteria.Template == ExportTemplate.Default) 
{ 
    // Retrieve additional columns from "columns" expression tree 
} 

return _divisionTeamsRepository.GetPagedResults(criteria.Page, criteria.PageSize, @where.Expand(), string.Format("{0} {1}", criteria.SortOrder, criteria.SortDirection), columns); 
+0

http://stackoverflow.com/questions/16516971/linq-dynamic-select:実際には、あなただけのexisting library(私が作者だスポイラー)を使用することができます –

+3

'columns = d => {var c = columns();の何が問題なのですか。 c.OtherProperty = d.OtherProperty;戻り値c; } '?あなたが試したこと、そしてあなたが何か問題を抱えていることについてもっと具体的にしてください。あなたの質問は現時点では非常に広いです。 –

+0

私はすでにそれをしたとは思わない?このエラーが発生したため、テストしなかったようです。 '文の本文を持つラムダ式は式ツリーに変換できません ' –

答えて

2

考える二つの「セレクタ」の表現は、あなたが彼らのMemberInitExpressionからバインディングを取り、すべてのバインディングを使用して、新しい式を作成しました。しかし、この式は1つのパラメータに対して2つの異なるパラメータ式を使用するため、動作しません。私たちもそれを修正する必要があります。考える

...

Expression<Func<TSource, TResult>> left = ... // columns 
Expression<Func<TSource, TResult>> right = ... // more columns 

...バインディングを取る...

var leftInit = left.Body as MemberInitExpression; 
var rightInit = right.Body as MemberInitExpression; 

var bindings = leftInit.Bindings.Concat(rightInit.Bindings); 

...新しい式を作成...

var result = Expression.Lambda<Func<TSource, TResult>>(
    Expression.MemberInit(Expression.New(typeof(TResult)), bindings), ???); 

..しかし、単一のパラメータが必要です...

var binder = new ParameterBinder(left.Parameters[0], right.Parameters[0]); 
var bindings = binder.Visit(leftInit.Bindings.Concat(rightInit.Bindings)); 

// now, just use right.Parameters[0] as parameter... 

そして、パラメータを交換すると表現の訪問者を使用してうまく機能:この配管のものを抽象化

class ParameterBinder : ExpressionVisitor 
{ 
    readonly ParameterExpression parameter; 
    readonly Expression replacement; 

    public ParameterBinder(ParameterExpression parameter, Expression replacement) 
    { 
     this.parameter = parameter; 
     this.replacement = replacement; 
    } 

    protected override Expression VisitParameter(ParameterExpression node) 
    { 
     if (node == parameter) 
      return replacement; 

     return base.VisitParameter(node); 
    } 
} 

はかなりうまく動作します。 、そのようなことにつながるはずです。

var merged = columns.Apply(moreColumns); 
+0

@Mikeはそれを助けますか? (あなたの恩恵は2日以内に終了します...) –

関連する問題