2011-09-12 63 views
1

爲什麼...LINQ2SQL和lambda收益 「方法 'System.Object的DynamicInvoke(System.Object的[])' 有沒有支持轉換爲SQL」

Func<IQueryable<CampaignCodePaths>> table =() => CampaignCodePaths; 

Func<CampaignCodePaths, int> propertySelector = e => e.Id; 

int key = 1; 

Func<CampaignCodePaths, bool> whereSelector = e => propertySelector(e).Equals(key); 

table().Where(whereSelector).FirstOrDefault(); 

...工作,但...

Func<IQueryable<CampaignCodePaths>> table =() => CampaignCodePaths; 

Func<CampaignCodePaths, int> propertySelector = e => e.Id; 

int key = 1; 

table().Where(e => propertySelector(e).Equals(key)).FirstOrDefault(); 

...返回例外:

方法 'System.Object的DynamicInvoke(System.Object的[])' 有沒有支持轉換爲SQL

UPDATE

澄清:

CampaignCodePath Get(Func<IQueryable<CampaignCodePaths>> table, Func<CampaignCodePaths, int> selector, int key) 
{ 
    return table().Where(/*How to I create this expression from selector and key? */).FirstOrDefault(); 
} 

... 

Get(() => CampaignCodePaths, e => e.Id, 1) 

回答

4

你的代碼的第一塊在.NET中執行所有的過濾,因爲你正在使用的,而不是一個表達式樹的委託 - 它甚至沒有嘗試將過濾器轉換爲SQL。換句話說,並不是第一個「有效」,第二個不是 - 第一個不會失敗,因爲它並不真正去做你期望的事情,而第二個事情就是這樣。

第二種形式是呼叫Queryable.Where(IQueryable<T>, Expression<...>)而第一種呼叫Enumerable.Where(IEnumerable<T>, Func<...>)

如果你改變你的代碼:

Expression<Func<CampaignCodePaths, bool>> filter = e => e.Id.Equals(key); 
table().Where(filter).FirstOrDefault(); 

那麼它應該是罰款。

編輯:在回答您的編輯,我覺得你想要的東西,如:

CampaignCodePath Get(Func<IQueryable<CampaignCodePaths>> table, 
        Expression<Func<CampaignCodePaths, int> selector>, 
        int key) 
{ 
    Expression equal = Expression.Equal(selector, Expression.Constant(key)); 
    var lambda = Expression.Lambda<Expression<Func<CampaignCodePaths, bool>> 
     (equal, selector.Parameters); 
    return table().Where(lambda).FirstOrDefault(); 
} 
+0

好,感謝察覺的!你能解釋一下我可以如何使用Expression嗎? –

+0

@Niels:已經稍微更新了答案 - 你應該可以放下。 –

+0

唯一的問題是過濾器是在其他地方定義的。關鍵是需要動態地「綁定」到文件管理器。有可能做一些咖喱魔法嗎? –

相關問題