2010-04-19 86 views
5

我的IQueryable行是:Linq按列表<T>(System.Collection.Generic.List)對象過濾IQueryable對象<T>(System.Data.Linq.DataQuery)對象嗎?

// find all timesheets for this period - from db so System.Data.Linq.DataQuery 
var timesheets = _timesheetRepository.FindByPeriod(dte1, dte2); 

我的列表行是:

// get my team from AD - from active directory so System.Collection.Generic.List 
var adUsers = _adUserRepository.GetMyTeam(User.Identity.Name); 

我想只顯示時間表的時間表集合中所存在的用戶集合中的用戶。

如果我用一個標準的C#表達,如:

var teamsheets = from t in timesheets 
        join user in adUsers on t.User1.username equals user.fullname 
        select t; 

我得到的錯誤「它返回一個自我參照的常量表達式的IQueryable不支持」

任何建議?

+0

球隊有多大? – SteadyEddi 2010-04-19 08:37:19

+0

如果每個團隊不超過20個用戶 - 那麼.contains應該支持 – Klaptrap 2010-04-19 12:45:27

回答

3

連接構造不起作用,但您可以使用Contains方法。這下一個片段可能會訣竅。

string[] usernames = adUsers.Select(u => u.fullname).ToArray(); 

var teamsheets = 
    from t in timesheets 
    where usernames.Contains(t.User1.username) 
    select t; 
+0

破解它 - 謝謝 – Klaptrap 2010-04-19 08:50:28

4

Linq to Sql會嘗試生成一個sql查詢來表示整個表達式。這意味着它會嘗試將廣告用戶的集合作爲參數傳遞給SQL查詢。如果用戶太多,查詢將會觸及參數限制(2100),並且無法執行。如果團隊中沒有那麼多的用戶,那麼你可以使用一個包含表達式,它將在sql中轉換爲「IN」表達式。

這是史蒂芬曾建議:

string[] usernames = adUsers.Select(u => u.fullname).ToArray(); 

var teamsheets = 
from t in timesheets 
where usernames.Contains(t.User1.username) 
select t; 

只有這樣,才能在使用中所嘗試的方式連接就可以從數據庫中檢索所有的時間表到內存(使用ToList時間表var),然後連接將發生在內存中。如果這比使用Contains更好,或者因爲團隊規模而無法使用Contains,這可能值得考慮。

+0

感謝您的額外解釋 - 這一切都有其道理。 – Klaptrap 2010-04-19 08:57:59