2010-03-26 176 views
4

我有本地的記錄Id集合(整數)。Linq to SQL問題

我需要檢索有子女的記錄,當地收集IDS中的每一個記錄。

這裏是我的查詢:

public List<int> OwnerIds { get; private set; } 
... 
filteredPatches = from p in filteredPatches 
        where OwnerIds.All(o => p.PatchesOwners.Select(x => x.OwnerId).Contains(o)) 
        select p; 

我收到此錯誤:

Local sequence cannot be used in Linq to SQL implementation of query operators except the Contains() operator.

我明白。所有()不是由LINQ到SQL支持,但有什麼辦法做我想做的事情?

回答

1

客戶那裏 OrderIds孩子收集是在內存中的集合中的ID的子集。

from c in myDC.Customer 
where c.Orders.All(o => myList.Contains(o.ID)) 
select c; 

客戶那裏 OrderIds在內存中的集合是孩子集合中的ID的子集。

from c in myDC.Customers 
where (from o in c.Orders 
    where myList.Contains(o.ID) 
    group o.ID by o.ID).Distinct().Count() == myList.Count() 
select c; 

客戶在內存中集合在 OrderIds被設置等於孩子集合中的ID。

from c in myDC.Customers 
let Ids = c.Orders.Select(o => o.ID).Distinct() 
where Ids.Count() == myList.Count() 
    && Ids.All(id => myList.Contains(id)) 
select c; 

所有這些都爲我生成了sql。

PS - 這些假定ID已經在myList中不同。如果它們尚未使用,請使用:

myList = myList.Distinct().ToList(); 

PSS - 適用於列表最多約2000個項目。高於該值將被轉換爲sql,然後sql服務器將會在參數數量上發生變化。

0

你可以做一個加入OwnerIds?

1

我不知道的方式使用LINQ做它的SQL。問題是你需要將你的列表放到服務器上,以便它可以查詢它。 (您的列表是在您的計算機上存儲,SQL Server需要做服務器上過濾)

有了直接的SQL,你可以使用常規的SELECT語句的「在()」操作符來做到這一點。 (在「in」中不要超過1,000個項目)

您可以將所有ID插入到SQL中的臨時表中,然後連接到表(您可以使用LINQ與此解決方案配合使用,但它需要2個步驟 - 插入(假設你有一個「sets」表),然後加入查詢(然後清除查詢以刪除你的集合)。

你可以LINQ查詢而不需要篩選條件,然後篩選(不建議如果未過濾的結果集可能很大)

+0

「包含運算符除外」。 – 2010-03-26 20:33:58

+0

另外 - 爲什麼不在「in」中超過1000個項目?我做了這麼多次沒有後果。 – 2010-03-26 21:07:11

+0

@DavidB - 不知道包含運算符。這就是爲什麼我說「我不知道一種方式......」,而不是「不」。至於超過1,000項我們實際測試過的項目,並發現在某些情況下,您的查詢性能將會下降。如果您的項目超過1,000個,則可以通過將其分解爲2個或更多個查詢來獲得更好的查詢性能。 – JMarsch 2010-03-26 22:40:40

0

錯誤說「本地序列(意味着OwnerIds)不能用於查詢運算符的SQL實現除了載有()操作符「 所以,你可以這樣做:。

1)從SQL

var loadedData = filteredPatches.Select(i => i).ToList(); 

2)過濾數據作爲簡單的本地序列

var result = loadedData.Where(i => i.PatchesOwners.All(o => OwnerIds.Contains(o.ID))); 
1

編譯器說什麼加載所有filteredPatches行是...

OwnerIds.Contains(someVariable) 

支持,它將被翻譯爲:

WHERE someVariable IN (OwnerId1, OwnerId2, OwnerIdN) 

現在,我們沒有所有的信息你查詢,但如果你能重新制定你正在試圖做的使用Contains什麼,你會沒事的。

+0

如果你想驗證每個列表中有東西,你可以使用'not Any(不包含(...))' – 2010-03-26 21:08:28