如何创建最佳查询?

时间:2012-11-24 10:33:18

标签: c# linq self-join

我有一个数据库中的菜单项列表,如:

ID      ParentID      ItemOrder      Name
-------------------------------------------------------    
 1       null               1        Main_1
 2       null               2        Main_2
 3       null               3        Main_3
 4       null               4        Main_4
 5       null               5        Main_5
 6       1                  4        SubMenu_1.4
 7       1                  5        SubMenu_1.5
 8       1                  8        SubMenu_1.8
 9       2                  1        SubMenu_2.1
10       3                  1        SubMenu_3.1
11       3                  2        SubMenu_3.2
12       3                  4        SubMenu_3.4

Submenu ItemOrder可能不一定从1开始,它可能以3开头,以下菜单项顺序可以是7,依此类推。

如何创建将返回所有父级(零级别)菜单项及其第一个子级(如果存在)的linq查询或lambda表达式?

预期结果:

ID      ParentID      ItemOrder      Name
-------------------------------------------------    
 1       null             1          Main_1
 2       null             2          Main_2
 3       null             3          Main_3
 4       null             4          Main_4
 5       null             5          Main_5
 6       1                4          SubMenu_1.4
 9       2                1          SubMenu_2.1
10       3                1          SubMenu_3.1

3 个答案:

答案 0 :(得分:1)

var items = dbContext.Table
    .Where(item => item.ParentID == null)
    .Union(dbContext.Table
        .Where(x => x.ParentID != null)
        .GroupBy(x => x.ParentID)
        .Select(g => g.FirstOrDefault()));

答案 1 :(得分:0)

public IQueryable<MenuItem> MakeQuery()
{

    var parentsQuery =
        from parent in ctx.MenuItem
        where parent.ParentID == null
        orderby parent.ItemOrder
        select parent;

    var childrenQuery =
        from parent in parentsQuery
        join child in ctx.MenuItem
            on parent.ID equals child.ParentID
        where !ctx.MenuItem.Any(child2 => child2.ParentID == parent.ID
            && child2.ItemOrder < child.ItemOrder)
        orderby child.ItemOrder
        select child;

    return parentsQuery.Concat(childrenQuery);
}

这可以避免错误“联合或Concat中的类型构造不兼容”。从LINQ到SQL,只返回第一级子级。

答案 2 :(得分:0)

我会使用此查询

    var parents = table.Where(i => i.ParentID == null);
    var immediateChildren = table
        .GroupBy(i => i.ParentID)
        .Select(g => g.OrderBy(i => i.ItemOrder).FirstOrDefault());
    var result = parents.Union(immediateChildren);

结果仅包括所请求的直接子项,变量有助于了解正在发生的事情。