2010-03-26 122 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