如何订购匿名类型组内的项目?

时间:2021-01-31 11:53:39

标签: linq anonymous

我想以匿名对象组的形式获得 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

2 个答案:

答案 0 :(得分:0)

您可以更新 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); ;
            }
        }
    }

答案 1 :(得分:0)

唉,你没有准确地描述你的需求在哪里,只是你想要一些匿名类型并且它们应该按 Id 排序。您的查询语法与您的方法语法构成不同的组。所以我只能举个例子来创建你的匿名对象序列

所以你有一系列相似的项目,其中每个项目至少有属性 Id 和 IdOperation。您希望将项目分组,其中每个组中的每个项目都具有相同的 IdOperation 值。您想按 Id 升序对每个组中的元素进行排序,并创建一些匿名类型。

你没有在你的匿名对象中指定你想要什么(毕竟:你的代码没有做你想要的,所以我不能从你的代码中扣除)

每当我使用 GroupBy,并且我想指定每个组的元素时,我都会使用 overload of GroupBy that has a parameter resultSelector。使用 resultSelector 我可以精确地定义组的元素。 (链接指的是IQueryable,还有一个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 是从一组中的所有元素和公共组值创建的一个对象。

相关问题