2012-03-21 53 views
2

說,我有這些在派生類中重寫的屬性。結合相同輸入類型的選擇表達式

protected virtual Expression<Func<TEntity, long>> GetIDExpr { get; } 
protected virtual Expression<Func<TEntity, string>> GetNameExpr { get; } 
protected virtual Expression<Func<TEntity, long>> GetValueExpr { get; } 

現在說我有這個類

public class MyData 
{ 
    public long ID { get; set; } 
    public string Name { get; set; } 
    public long Value { get; set; } 
} 

現在,在基類,我怎麼會做出Expression<Func<TEntity, MyData>>的是,在被調用時,將填充每個字段,並允許我創造了一種方法,返回IEnumerable<MyData>

我想避免使用Invoke,因爲我只想從數據庫中選擇這3個字段。

注意:爲了本示例的目的,將每個屬性視爲每次調用時都返回同一個Expression實例,而不是每次都創建一個新實例。

編輯:

這裏是我的嘗試,這是行不通的:

public IEnumerable<MyData> GetAllData(IQueryable<TEntity> table) { 
    ParameterExpression parameter = Expression.Parameter(typeof(TEntity), "obj"); 

    List<MemberBinding> bindings = new List<MemberBinding> { 
     Expression.Bind(typeof(MyData).GetProperty("ID"), GetIDExpr.Body), 
     Expression.Bind(typeof(MyData).GetProperty("Name"), GetNameExpr.Body), 
     Expression.Bind(typeof(MyData).GetProperty("Value"), GetValueExpr.Body), 
    }; 

    var selector = Expression.MemberInit(Expression.New(typeof(MyData).GetConstructor(Type.EmptyTypes)), bindings); 

    var getBar = Expression.Lambda<Func<TEntity, MyData>>(selector, parameter); 

    return table.Select(getBar); 
} 

在這裏,我得到在執行查詢一個ArgumentException,說

的參數'obj'沒有綁定在指定的LINQ to Entities查詢表達式中。

我認爲這意味着使用.Body作爲值表達式不會工作,因爲不再有一個參數。但是,如果我不使用.Body,我上.Bind方法的異常

參數類型不匹配

回答

0

我不知道的方式組裝其他表達式樹在lambda表達式中表達樹,所以我認爲你必須以編程方式構建樹。本MSDN文章(How to: Use Expression Trees to Build Dynamic Queries)顯示瞭如何使用表達式樹API來構建表達式樹。

在這種情況下,您需要一個new表達式,後跟三個屬性分配;我不認爲你可以在表達式樹中做到這一點。你可以通過創建一個分配屬性的構造函數來解決這個問題。

+0

CONSTRUCTOR!我會放棄一下,歡呼。 – Connell 2012-03-21 17:05:05

+0

只有無參數的構造函數在LINQ to Entities中受支持。我知道會發生。任何機會我可以結合Expression.Assign語句? – Connell 2012-03-21 17:42:26