我有两个模型,其中两个模型都包含一个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; }
}
答案 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的任何业务,即具有与请求的子类别匹配的子类别的任何业务。