【问题标题】:How to query ICollection?如何查询ICollection?
【发布时间】:2014-09-08 16:12:15
【问题描述】:

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

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

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

我想查询商家并获取其子类别与请求中的商家匹配的商家(即使一个匹配就足够了)。我有这样的东西,我只是作为示例写的,当然它不起作用(请求是请求类型):

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

例如,假设我们有两个业务,其中第一个包含足球和篮球作为子类别,第二个包含篮球和网球。然后,假设我们的用户同时选择了 Football 和 Tennis 子类别,所以我的查询应该返回这两个业务,因为第一个包括 Football,第二个包括 Tennis。

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

这也是我的子类别模型,以备不时之需:

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

    public string SubcategoryName { get; set; }
}

【问题讨论】:

  • 这是在 ORM 中运行还是在 Linq2Objects 中运行?
  • var businesses = db.Users.OfType&lt;Business&gt;().Where(b =&gt; b.Subcategories.Where(s =&gt; s.SubcategoryName == subcategory.SubcategoryName)); 当您通过代码时,您对企业的价值是什么......我猜您还没有通过代码
  • Where 返回一个可枚举的,所以你的第一个 Where 就像 Where (b=>EnumerableButBoolExpected)
  • 不要在你的问题中说“它不起作用”。始终告诉我们您收到的错误信息,或具体描述不良行为。

标签: c# linq collections


【解决方案1】:

我会这样做:

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 的任何业务,即任何具有与请求的子类别匹配的子类别的业务。

【讨论】:

    【解决方案2】:

    查看您的 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 的使用。 Any 返回一个boolean 值,指示是否找到与您的谓词s =&gt; s.SubcategoryName == subcategory.SubcategoryName 匹配的记录

    【讨论】:

    • 这可行,但它仍然需要通过 request.Subcategories 使用 foreach 循环。它还生成多个匹配业务集合 - request.Subcategories 中的每个类别一个。这是想要的吗?我认为所有匹配项的所有业务列表都是理想的结果。如果使用 Intersect(),则可以通过向 LINQ 查询添加一个子句来完全摆脱循环,并获得一个结果集合。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 2011-02-25
    • 2021-10-22
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多