如何在匿名类型的组内订购商品?
How to order items within the group of anonymous type?
我想获得 Linq 查询的结果作为匿名对象组。组内的项目应按 ID
字段排序。我可以部分地通过 lambda 语法达到这一点,但结果无法获得匿名对象。所以我需要每个例子的一部分。
可执行代码:https://dotnetfiddle.net/cPJUN9
var res_g = (from dg in list
group new { dg.ID, dg.IDOperation, dg.IDDiagnosis } by dg.IDOperation
into dg_group
select dg_group);
lambda 语法
var res_g = list
.GroupBy(x => x.IDOperation)
.Select(x => x.OrderBy(x => x.ID)); // order dg by ID asc within group
您可以更新 GetDict 函数内循环以对组元素使用 orderby
public static void GetDict(List<Operation> list)
{
var res_g = (from dg in list
group new { dg.ID, dg.IDOperation, dg.IDDiagnosis } by dg.IDOperation
into dg_group
select dg_group);
foreach (var x in res_g)
{
Console.WriteLine("Key: " + x.Key);
foreach (var y in x.OrderBy(o=>o.ID))
{
Console.WriteLine("{0} {1} {2}", y.ID, y.IDOperation, y.IDDiagnosis); ;
}
}
}
我希望这能解决问题。
根据您的要求编辑,但我正在调整结果集
var res_g_2 = list.Select( p=> new { p.ID, p.IDOperation, p.IDDiagnosis }) .GroupBy(g => g.IDOperation)
.Select(g => new {
IDOperation = g.Key,
Records = g.OrderBy(group => group.ID)
});
编辑完整版
public static void GetDict(List<Operation> list)
{
var res_g = (from dg in list
group new { dg.ID, dg.IDOperation, dg.IDDiagnosis } by dg.IDOperation
into dg_group
select new
{
Key = dg_group.Key,
Records = dg_group.OrderBy(g => g.ID)
}) ;
var res_g_2 = list.Select( p=> new { p.ID, p.IDOperation, p.IDDiagnosis }) .GroupBy(g => g.IDOperation)
.Select(g => new {
Key = g.Key,
Records = g.OrderBy(group => group.ID)
});
// you can use either res_g or res_g_2 both give the same results
foreach (var x in res_g)
{
Console.WriteLine("Key: " + x.Key);
foreach (var y in x.Records)
{
Console.WriteLine("{0} {1} {2}", y.ID, y.IDOperation, y.IDDiagnosis); ;
}
}
}
唉,你没有准确描述你的需求,只是说你想要一些匿名类型,并且它们应该按 Id 排序。您的查询语法与您的方法语法组成不同的组。所以我只能举个例子来创建你的匿名对象序列
所以你有一系列相似的项目,其中每个项目至少有属性 Id 和 IdOperation。您希望对项目进行分组,其中每个组中的每个项目都具有相同的 IdOperation 值。您想按 Id 升序对每个组中的元素进行排序,并创建一些匿名类型。
你没有在你的匿名对象中指定你想要什么(毕竟:你的代码没有做你想要的,所以我不能从你的代码中扣除它)
每当我使用 GroupBy 时,我想指定每个组的元素,我使用 overload of GroupBy that has a parameter resultSelector. With the resultSelector I can precisely define the elements of the group. (The link refers to IQueryable, there is also an IEnumerable version)
IEnumerable<Operations> operations = ... // = your list
// Make Groups of Operations that have the same value for IdOperation
var result = operations.GroupBy(operation => operation.IdOperation,
// parameter resultSelector: take the key (=idOperation) and all Operations that have
// this idOperation, to make one new.
(idOperation, operationsWithThisId) => new
{
// do you need the common idOperation?
IdOperation = idOperation,
// Order the elements in each group by Id:
Operations = operationsWithThisId.OrderBy(operation => operation.Id)
.Select(operation => new
{
// Select only the operation properties that you plan to use
Id = operation.Id,
Name = operation.Name,
StartDate = operation.StartDate,
...
})
.ToList(),
});
换句话说:从您的操作序列中,创建具有相同 IdOperation 值的操作组。然后采用这个通用的 IdOperation 以及该组中的所有操作来创建一个匿名对象:这就是您正在谈论的匿名对象。所以每组,你做一个匿名对象。
- IdOperation 是该组中所有操作共有的值
- 操作是一个列表。该组中的所有操作均按升序 Id 排序。选择了几个属性并将结果放入列表中。
如果您想以不同的方式分组,就像在查询语法中一样,只需更改参数 keySelector:
var result = operations.GroupBy(operation => new
{
Id = operation.ID,
IdOperation = operation.IDOperation,
IdDiagnosis = operation.IDDiagnosis
},
虽然这与您在查询语法中所做的相对应,但您将拥有具有相同 Id / IdOperation / IDDiagnosis 值的操作组。分组中的元素按Id排序是没有用的,因为这个分组中的所有Id都是相等的。
结论
使用参数 resultSelector,您可以完全按照需要定义结果:结果不是 IEnumerable<IGrouping<Tkey, TElement>>
,而是 IEnumerable<TResult>
.
TResult 是一个 从一个组中的所有元素和公共组值创建的对象。
我想获得 Linq 查询的结果作为匿名对象组。组内的项目应按 ID
字段排序。我可以部分地通过 lambda 语法达到这一点,但结果无法获得匿名对象。所以我需要每个例子的一部分。
可执行代码:https://dotnetfiddle.net/cPJUN9
var res_g = (from dg in list
group new { dg.ID, dg.IDOperation, dg.IDDiagnosis } by dg.IDOperation
into dg_group
select dg_group);
lambda 语法
var res_g = list
.GroupBy(x => x.IDOperation)
.Select(x => x.OrderBy(x => x.ID)); // order dg by ID asc within group
您可以更新 GetDict 函数内循环以对组元素使用 orderby
public static void GetDict(List<Operation> list)
{
var res_g = (from dg in list
group new { dg.ID, dg.IDOperation, dg.IDDiagnosis } by dg.IDOperation
into dg_group
select dg_group);
foreach (var x in res_g)
{
Console.WriteLine("Key: " + x.Key);
foreach (var y in x.OrderBy(o=>o.ID))
{
Console.WriteLine("{0} {1} {2}", y.ID, y.IDOperation, y.IDDiagnosis); ;
}
}
}
我希望这能解决问题。
根据您的要求编辑,但我正在调整结果集
var res_g_2 = list.Select( p=> new { p.ID, p.IDOperation, p.IDDiagnosis }) .GroupBy(g => g.IDOperation)
.Select(g => new {
IDOperation = g.Key,
Records = g.OrderBy(group => group.ID)
});
编辑完整版
public static void GetDict(List<Operation> list)
{
var res_g = (from dg in list
group new { dg.ID, dg.IDOperation, dg.IDDiagnosis } by dg.IDOperation
into dg_group
select new
{
Key = dg_group.Key,
Records = dg_group.OrderBy(g => g.ID)
}) ;
var res_g_2 = list.Select( p=> new { p.ID, p.IDOperation, p.IDDiagnosis }) .GroupBy(g => g.IDOperation)
.Select(g => new {
Key = g.Key,
Records = g.OrderBy(group => group.ID)
});
// you can use either res_g or res_g_2 both give the same results
foreach (var x in res_g)
{
Console.WriteLine("Key: " + x.Key);
foreach (var y in x.Records)
{
Console.WriteLine("{0} {1} {2}", y.ID, y.IDOperation, y.IDDiagnosis); ;
}
}
}
唉,你没有准确描述你的需求,只是说你想要一些匿名类型,并且它们应该按 Id 排序。您的查询语法与您的方法语法组成不同的组。所以我只能举个例子来创建你的匿名对象序列
所以你有一系列相似的项目,其中每个项目至少有属性 Id 和 IdOperation。您希望对项目进行分组,其中每个组中的每个项目都具有相同的 IdOperation 值。您想按 Id 升序对每个组中的元素进行排序,并创建一些匿名类型。
你没有在你的匿名对象中指定你想要什么(毕竟:你的代码没有做你想要的,所以我不能从你的代码中扣除它)
每当我使用 GroupBy 时,我想指定每个组的元素,我使用 overload of GroupBy that has a parameter resultSelector. With the resultSelector I can precisely define the elements of the group. (The link refers to IQueryable, there is also an IEnumerable version)
IEnumerable<Operations> operations = ... // = your list
// Make Groups of Operations that have the same value for IdOperation
var result = operations.GroupBy(operation => operation.IdOperation,
// parameter resultSelector: take the key (=idOperation) and all Operations that have
// this idOperation, to make one new.
(idOperation, operationsWithThisId) => new
{
// do you need the common idOperation?
IdOperation = idOperation,
// Order the elements in each group by Id:
Operations = operationsWithThisId.OrderBy(operation => operation.Id)
.Select(operation => new
{
// Select only the operation properties that you plan to use
Id = operation.Id,
Name = operation.Name,
StartDate = operation.StartDate,
...
})
.ToList(),
});
换句话说:从您的操作序列中,创建具有相同 IdOperation 值的操作组。然后采用这个通用的 IdOperation 以及该组中的所有操作来创建一个匿名对象:这就是您正在谈论的匿名对象。所以每组,你做一个匿名对象。
- IdOperation 是该组中所有操作共有的值
- 操作是一个列表。该组中的所有操作均按升序 Id 排序。选择了几个属性并将结果放入列表中。
如果您想以不同的方式分组,就像在查询语法中一样,只需更改参数 keySelector:
var result = operations.GroupBy(operation => new
{
Id = operation.ID,
IdOperation = operation.IDOperation,
IdDiagnosis = operation.IDDiagnosis
},
虽然这与您在查询语法中所做的相对应,但您将拥有具有相同 Id / IdOperation / IDDiagnosis 值的操作组。分组中的元素按Id排序是没有用的,因为这个分组中的所有Id都是相等的。
结论
使用参数 resultSelector,您可以完全按照需要定义结果:结果不是 IEnumerable<IGrouping<Tkey, TElement>>
,而是 IEnumerable<TResult>
.
TResult 是一个 从一个组中的所有元素和公共组值创建的对象。