LINQ许多与In或包含条款(和扭曲)

时间:2011-02-24 05:43:40

标签: c# linq linq-to-sql

我有许多名为PropertyPets的表结构。它包含一个双主键,包括PropertyID(来自Property表)和一个或多个PetID(来自Pet表)。

接下来,我有一个搜索屏幕,人们可以从jquery多选下拉列表中选择多个宠物。假设有人选择了Dogs and Cats。

现在,我希望能够在多对多的表PropertyPets中返回包含BOTH狗和猫的所有属性。我正在尝试使用Linq to Sql。

我查看了Contains子句,但它似乎不符合我的要求:

var result = properties.Where(p => search.PetType.Contains(p.PropertyPets));

这里,search.PetType是Dog和Cat的Id的int []数组(在多个选择下拉列表中选择)。问题首先,Contains需要一个字符串而不是PropertyPet类型的IEnumerable。其次,我需要找到同时拥有狗和猫的属性,而不仅仅是包含其中一个或另一个。

感谢您的任何指示。

2 个答案:

答案 0 :(得分:5)

您可以使用嵌套的where子句执行此操作。

您需要使用p.PropertyPets过滤contains - 返回PetID位于search.PetType的所有行。

然后只返回properties中已找到所有搜索ID的行 - 例如number of rows >= number of serach id's

所有在一起:

var result = from p in properties
             where p.PropertyPets.Where(c => search.PetType.Contains(c.PetID)).Count() >= search.PetType.Count()
             select p;

答案 1 :(得分:0)

对于Contains要求string不适用的部分,如果Containssearch.PetType,则int[]应该要求为int。这意味着您需要将p.PropertyPets“转换”为int。要将p.PropertyPets转换为IEnumerable<int>,您需要选择PropertyID字段:p.PropertyPets.Select(propertyPet => propertyPet.PropertyID),但这不会为您提供所需的单个int,而是一大堆。 (.First()会给你一个int但不能解决你的问题。

你真正想做的是

var result = properties.Where(p =>
    search.PetType.Except(p.PropertyPets.Select(propertyPet => 
                            propertyPet.PropertyID)).Count() == 0);

但LINQ2SQL中没有Except

我能找到的最佳选择是对Contains中的每个项目应用search.PetType

这样的事情:

var result = properties;
foreach(var petType in search.PetType)
{
    result = from p in result
             where p.PropertyPets.Select(propertyPet =>
                   propertyPet.PropertyID).Contains(petType)
             select p;
}