在多个中介中选择

本文关键字:选择 | 更新日期: 2023-09-27 18:30:51

我正在尝试构建这个对象:

[
    {
        "color" : "red",
        "category" : "tshirts",
        "Items" : [
            {
                "r" : 1,
                "n" : "name: E624E",
                "s" : 9819217.000
            }, {
                "r" : 2,
                "n" : "name: 00F37",
                "s" : 9791564.000
            }, {
                "r" : 3,
                "n" : "name: 75B02",
                "s" : 9790543.000
            }, {
                "r" : 4,
                "n" : "name: 08864",
                "s" : 9485392.000
            }
        ]
    }, 
    {
        "color" : "red",
        "category" : "shoes",
        "Items" : [
            {
                "r" : 1,
                "n" : "name: 20272",
                "s" : 9949541.000
            }, {
                "r" : 2,
                "n" : "name: 1E496",
                "s" : 9926730.000
            }, {
                "r" : 3,
                "n" : "name: 00F37",
                "s" : 9926493.000
            }, {
                "r" : 4,
                "n" : "name: 48A44",
                "s" : 9923929.000
            }
        ]
    }
]

我构建它的方式是使用 Linq,遍历颜色和类别的集合:

var colors = ctx.Colors.Select(x => x.Color).Distinct().ToList();
foreach (var color in colors)
{
    var categories = ctx.Categories.Where(x => x.Color == color).Select(x => x.Category).Distinct().ToList();
    foreach (var cat in categories)
    {
        List<ItemAttribute> iattr = (from i in ctx.Item
                                     where i.Color == color && i.Category == cat
                                     select new ItemAttribute { 
                                          r = i.R,
                                          n = i.N,
                                          s = i.S
                                      }).ToList();
        this.ItemStuff.Add(iattr);
    }
}

这有效,我得到了预期的结果,但性能很臭,看起来很冗长。

任何人都可以提供一些改进的见解吗?

在多个中介中选择

也许你正在寻找这样的东西:

var results = 
    from i in ctx.Items
    group i by new { i.Color, i.Category } into g
    select new ItemGroup
    {
        color = g.Key.Color,
        category = g.Key.Category
        items =
            (from i in g 
             select new ItemAttribute
             { 
                 r = i.R,
                 n = i.N,
                 s = i.S
             })
            .ToArray()
    };

或者用流畅的语法:

var results = ctx.Items
    .GroupBy(i => new { i.Color, i.Category })
    .Select(g => new ItemGroup
    {
        color = g.Key.Color,
        category = g.Key.Category
        items = g.Select(i => new ItemAttribute
                { 
                    r = i.R,
                    n = i.N,
                    s = i.S
                })
                .ToArray()
    };

您的代码在几个地方遵循相同的次优模式:您一次处理一种颜色或单个类别,而不是获取所有内容并按颜色或类别分组。当你遍历colors时,你可以在外部循环中这样做,然后在嵌套循环中做同样的事情,当你迭代categories

这会多次ctx,每次都有单独的查询。除了极少数例外,循环查询肯定会降低性能。最好获取所有内容,按颜色/类别分组,然后按照您需要的方式构建结果。

这是一种方法:

var items = ctx.Item.Select(i => new ItemAttribute { 
    r = i.R
,   n = i.N
,   s = i.S
})
.GroupBy(i => new { i.Color, i.Category })
.OrderBy(p => p.Key.Color)
.ThenBy(p => p.Key.Category);

此时,您有按颜色和类别分组的所有项目的组,在单个查询中检索。现在剩下的就是迭代组,并将数据添加到要填充的结构中。