如何查询ICollection?

时间:2014-09-08 16:12:16

标签: c# linq collections

我有两个模型,其中两个模型都包含一个ICollection对象,如下所示:

public class Business : ApplicationUser
{
    ...
    public virtual ICollection<Subcategory> Subcategories { get; set; }
    ...
}

public class Request
{
    ....
    public virtual ICollection<Subcategory> Subcategories { get; set; }
    ...
}

我想查询业务并获得其子类别与请求中的子类别匹配的业务(即使一个匹配就足够了)。我有类似的东西,我只是作为样本写的,当然它不起作用(请求类型为Request):

foreach (var subcategory in request.Subcategories)
{
    var businesses = db.Users
        .OfType<Business>()
        .Where(b => b.Subcategories
            .Where(s => s.SubcategoryName == subcategory.SubcategoryName));
}

所以,例如,让我们说我们有两个企业,第一个有足球和篮球作为子类别,第二个有篮球和网球。然后,让我们说我们的用户选择足球和网球子类别,所以我的查询应该返回两个业务,因为第一个包括足球,第二个包括网球。

因此,并非每个子类别都应该匹配,即使一个匹配也足以接受业务。我怎样才能实现它?如果你能提供代码,我会很高兴。

这也是我的子类别模型,如果您需要它:

public class Subcategory
{
    public int SubcategoryID { get; set; }

    public string SubcategoryName { get; set; }
}

2 个答案:

答案 0 :(得分:7)

查看Linq方法的签名。特别是Where

Enumerable.Where<TSource> Method (IEnumerable<TSource>, Func<TSource, Boolean>)

需要一个返回布尔值的谓词。 Where返回一个集合,因此您无法将其插入到期望Func返回布尔值的Where子句中;那不行。

你可能需要的是这样的东西:

var businesses = db.Users.OfType<Business>()
    .Where(b => b.Subcategories
    .Any(s => s.SubcategoryName == subcategory.SubcategoryName));

请注意Any的使用。任何返回boolean值,表示是否找到与您的谓词匹配的记录s => s.SubcategoryName == subcategory.SubcategoryName

答案 1 :(得分:3)

我会这样做:

var businesses = db.Users
    .OfType<Business>()
    .Where(b => b.Subcategories.Intersect(request.Subcategories)
    .Any());

打破这个局面:

b.Subcategories.Intersect(request.Subcategories);

将返回b.Subcategories和request.Subcategories中存在的那些类别的集合。

因此

b.Subcategories.Intersect(request.Subcategories).Any()

如果两者中都存在任何类别,则返回true,如果不存在则返回false。

最后:

db.Users.OfType<Business>()
        .Where(b => b.Subcategories.Intersect(request.Subcategories).Any());

将返回前一个语句返回true的任何业务,即具有与请求的子类别匹配的子类别的任何业务。