【问题标题】:How to Filter a Query On a One to Many Relationship via Linq如何通过 Linq 过滤一对多关系上的查询
【发布时间】:2017-05-04 16:38:13
【问题描述】:

我有一个产品和一个零件表。这是关联:

Create Table Product
{
   Id int,
   Name nvarchar(max)
}

Create Table Part
{
   Id int,
   Name nvarchar (max),
   ProductID int (foreign key to Product.Id),
   SomeCategoryId int
}

现在,我想返回一个产品列表,其中的部件列表仅包含 200 的 SomeCategoryId。

规则:

  • 如果 Part.SomeCategoryId 200,则不包括该 Part
  • 如果没有 Part.SomeCategoryId == 200 通过 Part.Product.Id 与 Product 对应,则删除整个 Product。

如何让下面的代码更有效率?

prods = db.Products.OrderBy(o => o.Name).Select(pr => new ProductViewModel
{
    Id = pr.Id,
    Name = pr.Name,
    Parts = pr.Parts.OrderBy(o => o.Name).Select(prt => new PartViewModel
    {
        Id = prt.Id,
        Name = prt.Name,
        SomeCategoryId = prt.SomeCategoryId
    }).Where(w => w.SomeCategoryId == 200).ToList()
}).ToList();

foreach(var prod in prods)
{
    var isSomeCategory = false;
    foreach (var part in prod.Parts)
    {
        if (part.SomeCategoryId == 200)
        {
            isSomeCategory = !isSomeCategory;
        }
    }

    if (isSomeCategory == false)
    {
        prods.Remove(prod);
    }
}

【问题讨论】:

  • 您只需要从最终结果中筛选出带有零件的产品。在内存中还是在数据库中执行此操作更有效,您可以尝试一下。

标签: c# .net entity-framework linq one-to-many


【解决方案1】:

怎么样...

prods = db.Products.Where(pr => pr.Parts.Any(p => p.SomeCategoryId == 200)).OrderBy(o => o.Name).Select(pr => new ProductViewModel
{
    Id = pr.Id,
    Name = pr.Name,
    Parts = pr.Parts.OrderBy(o => o.Name).Select(prt => new PartViewModel
    {
        Id = prt.Id,
        Name = prt.Name,
        SomeCategoryId = prt.SomeCategoryId
    }).Where(w => w.SomeCategoryId == 200).ToList()
}).ToList();

【讨论】:

  • 这太慢了!可能是因为我在 Parts 中完全没有数据?
  • 如果在选择之前移动 where 会更快吗?
猜你喜欢
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
相关资源
最近更新 更多