【问题标题】:LINQ: How to make a nested select statement conditional?LINQ:如何使嵌套的 select 语句有条件?
【发布时间】:2012-05-07 03:23:04
【问题描述】:

我正在使用 EF 处理 ASP.NET 项目,但在查找正确查询时遇到了一些麻烦。 我需要在没有延迟加载的情况下工作。

我有以下数据结构: 一个模块包含页面。 Page 包含 PageItem。 PageItem 包含一个项目。 一个 Item 可以包含其他 Item。

首先忽略包含项目的项目的递归方面,我需要一个查询来将单个模块的结构提供给树视图。

我想要的是:

  • 具有给定 ID 的模块
    • 包括所有页面
      • 包括所有页面项
        • 包括 ParentItem_ID == 0 的所有项目
          • 包括所有 ChildItems

我是从这个开始的:

return base._entities.Modules
            .Include(m => m.Paginas
                .Select(p => p.PaginaItems
                    .Select(pi => pi.Item)
                    .Select(i => i.ChildItems)))
            .Where(m => m.Module_ID == id)
            .FirstOrDefault();

此查询有效,但它忽略了项目层次结构并将所有项目显示为页面的直接子项。实际需要的是这样的:

return base._entities.Modules
           .Include(m => m.Paginas
               .Select(p => p.PaginaItems
                   .Select(pi => pi.Item)
                   .Where(i => i.I_ParentItem_ID == 0)
                   .Select(i => i.ChildItems)))
           .Where(m => m.Module_ID == id)
           .FirstOrDefault();

但它不起作用。

我是一个相对较新的 LINQ,任何帮助都将不胜感激。

【问题讨论】:

  • 在这种情况下,您应该使用明确的joins。

标签: linq select include where


【解决方案1】:

由于您需要嵌套集合中的条件,您应该使用join,例如:

(from mod in c.Modules
join pag in c.Paginas on mod.Module_Id equals pag.Module_Id
join pi in c.PaginaItems on pag.Pagina_Id equals pi.Pagina_Id
join item in c.Items.Where(i => i.I_ParentItem_ID == 0) on pi.PaginaItem_Id
    equals item.PaginaItem_Id
join ci in c.ChildItems on item.I_ParentItem_ID equals ci.I_ParentItem_ID
select mod).FirstOrDefault()

我将 base._entities 缩写为 c(用于上下文)并对 Id 名称进行了一些假设,并且可能忽略了奇怪的语法错误,但这应该是一个好的开始。

【讨论】:

  • 哇,这真的很有帮助。现在我明白了。虽然我不得不稍微修改一下查询:我必须编写 select new{mod,pag,pi,item} 而不是 select mod 然后返回 qry.mod,否则 Module 的导航属性为 null。
猜你喜欢
  • 2010-09-12
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-09
  • 2016-10-22
  • 2011-06-07
  • 1970-01-01
相关资源
最近更新 更多