LINQ查询降序树

时间:2015-05-27 15:10:27

标签: c# linq

我有这个实体结构:

类别 - > 有很多“群组” - &gt; 有很多“类型” - &gt; 有很多“项目”< / p>

我需要通过 Item.Color ==“blue”过滤降序树(包括),即:

var tree = from c in db.Categories
                       .Include(ct =>
                                ct.Groups
                                  .Select(gr =>
                                          gr.Types
                                            .Select(pr => pr.Products)
                                         )
                               )
           join g in db.Groups on c.CategoryId equals g.CategoryId
           join t in db.Types on g.GroupId equals t.GroupId
           join i in db.Items on t.TypeId equals i.TypeId
           where i.Color == "blue" // example filter
           select c;

使用此查询我有降序树,但是我得到了其他颜色的项目。

我只需要降序树来获取蓝色项目。

谢谢!

1 个答案:

答案 0 :(得分:1)

我假设你正在使用EntityFramework。

您需要做的只是一直包含,然后在您的实体上使用.Any谓词。 E.g。

var tree = db.Categories.Include(ct => ct.Groups.Select(gr =>
                                          gr.Types.Select(pr => 
                                             pr.Products)))
           .Where(c => c.Groups.Any(g => 
                         g.Types.Any(t => 
                           t.Items.Any(i => 
                             i.Color == "blue"))))
           .ToList()

警告,如果某个类型有多个项目,并且只有1个为蓝色,您将获得所有项目,而不仅仅是蓝色项目。但如果一个类型没有蓝色项目,你就不会得到它。

如果您想在每个级别进行过滤,则需要在每个级别进行投影。

修改

因此,如果您想过滤,您有两个选择:

  1. 每个级别的投影
  2. 首先获取所有蓝色项目,然后检索其类型,组和类别。
  3. 实施例

    1。每个级别的预测

    var tree = db.Categories.Include(ct => ct.Groups.Select(gr =>
                                              gr.Types.Select(pr => 
                                                 pr.Products)))               
               .Where(c => c.Groups.Any(g => 
                             g.Types.Any(t => 
                               t.Items.Any(i => 
                                 i.Color == "blue"))))
               .Select(c => new { Groups = c.Groups.Where(g => 
                                             g.Types.Any(t => 
                                               t.Items.Any(i => 
                                                 i.Color == "blue"))
                                  .Select( g => new { Types = g.Types.Where(t => 
                                               t.Items.Any(i => 
                                                 i.Color == "blue"))
                                                      .Select(t => new { Items = t.Items.Where(i => 
                                                                                   i.Color == "blue")
               .ToList() // Return list of anonymous types (
    

    您无法投影实体类型,您必须首先检索匿名类型,然后使用Linq2Objects投影到实体类型,因为EF不允许您执行此操作。我经常做的是直接投影到准备显示的视图模型中。