如何在匿名类型的组内订购商品?

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 是一个 从一个组中的所有元素和公共组值创建的对象。