2017-05-06 69 views
4

如果我想要檢索更多列,並且已經存在如下所示的lambda樹表達式 ,我該怎麼做?這適用於實體框架,並希望它仍然有效。添加到Lambda表達式並使用實體框架

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 –

+3

'columns = d => {var c = columns(); c.OtherProperty = d.OtherProperty;返回c; }'?請更具體地說明您嘗試過的內容,以及您遇到的具體問題。你的問題目前非常廣泛。 –

+0

你不覺得我已經做到了嗎?看起來你沒有測試,因爲你得到這個錯誤。 '帶有語句正文的lambda表達式不能轉換爲表達式樹' –

回答

2

給定兩個「選擇」的表達,你從他們的MemberInitExpression採取綁定,並使用所有綁定一個新的表達式。但是這個表達式不起作用,因爲它爲一個參數使用了兩個不同的參數表達式。我們也需要解決這個問題。

鑑於...

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), ???); 

.. .BUT,需要單參數...

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); 
    } 
} 

這個抽象的東西水暖工作得很好。事實上,你可以只使用一個existing library(擾流板:我是作者),這應該引起類似的東西:

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

@Mike有幫助嗎? (你的賞金在2天內結束......) –