我正在尝试构建此对象:
[
{
"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);
}
}
这有效,我得到了理想的结果,但表现很糟糕,似乎很冗长。
任何人都可以提供一些改善这一点的见解吗?
答案 0 :(得分:3)
也许你正在寻找这样的东西:
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()
};
答案 1 :(得分:1)
您的代码在几个地方遵循相同的次优模式:您不是按照颜色或类别进行所有内容和分组,而是一次处理单个颜色或单个类别。当您遍历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);
此时,您拥有按颜色和类别分组的所有项目组,并在单个查询中检索。现在剩下的就是迭代这些组,并将数据添加到您正在填充的结构中。