将动态匿名对象添加到 linq groupBy 表达式中

Ant*_*sky 5 c# linq

我有以下 linq 表达式:

Func<Entity, object> groupQuery = item => 
     new { a = item.Attributes["name"], item = item.Attributes["number"] };
var result = target.Collection.Entities.GroupBy(groupQuery).ToList();
Run Code Online (Sandbox Code Playgroud)

但如果我不知道我将分组多少列(例如 3 个而不是 2 个),以及存储在列表名称中的属性名称,我应该如何更改我的 groupQuery 对象?我的第一个想法是创建这样的动态对象,但它不起作用

dynamic groupQuery= new ExpandoObject();
IDictionary<string, object> dictionary = (IDictionary<string, object>)groupQuery;

foreach (string str in Names)
{
   dictionary.Add(str, str);
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*sky 1

回答问题 C# LINQ - 如何动态构建 Group By 子句

IEnumerable<string> columnsToGroupBy = new[] { Names.First()};
            Names.RemoveAt(0);
            Names.Aggregate(columnsToGroupBy, (current, query) => current.Concat(new[] {query}));
            GroupQuery = r => new NTuple<object>(from column in columnsToGroupBy select r[column]);
///////
    using System;
    using System.Collections.Generic;
    using System.Linq;

    namespace WBTCB.AggregationService.Models.Helpers
    {
        public class NTuple<T> : IEquatable<NTuple<T>>
        {
            public NTuple(IEnumerable<T> values)
            {
                Values = values.ToArray();
            }

            public readonly T[] Values;

            public override bool Equals(object obj)
            {
                if (ReferenceEquals(this, obj))
                    return true;
                if (obj == null)
                    return false;
                return Equals(obj as NTuple<T>);
            }

            public bool Equals(NTuple<T> other)
            {
                if (ReferenceEquals(this, other))
                    return true;
                if (other == null)
                    return false;
                var length = Values.Length;
                if (length != other.Values.Length)
                    return false;
                for (var i = 0; i < length; ++i)
                    if (!Equals(Values[i], other.Values[i]))
                        return false;
                return true;
            }

            public override int GetHashCode()
            {
                return Values.Aggregate(17, (current, value) => current*37 + (!ReferenceEquals(value, null) ? value.GetHashCode() : 0));
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)