c# - 在 Group By 中使用表达式树后无法选择

标签 c# linq linq-to-sql lambda expression-trees

我一直在引用this post使用表达式树进行分组。这是我的代码:

String[] fields = { "DepartmentID", "SkillID" };
var groupLambda = GroupByExpression<Person>(fields);
var query = dbContext.People.GroupBy(groupLambda.Compile());
var queryResult = query.ToList();

这里是 GroupByExpression 方法,它使用上述帖子中给出的解决方案(感谢 Daniel !):

public static Expression<Func<TItem, object>> GroupByExpression<TItem>(string[] propertyNames)
{
var properties = propertyNames.Select(name => typeof(TItem).GetProperty(name)).ToArray();
var propertyTypes = properties.Select(p => p.PropertyType).ToArray();
var tupleTypeDefinition = typeof(Tuple).Assembly.GetType("System.Tuple`" + properties.Length);
var tupleType = tupleTypeDefinition.MakeGenericType(propertyTypes);
var constructor = tupleType.GetConstructor(propertyTypes);
var param = Expression.Parameter(typeof(TItem), "x");
var body = Expression.New(constructor, properties.Select(p => Expression.Property(param, p)));
var expr = Expression.Lambda<Func<TItem, object>>(body, param);
return expr;
}

我希望能够通过选择部分中具有强名称的键来识别组中的字段,例如 query.Select(x => new { x.Key.DepartmentID, x.Key.SkillID });

我该怎么做?

最佳答案

现在...我不会为您提供您提出的问题的解决方案,但我会尽力帮助您:-)

如果你想做动态查询,你可能应该使用 DynamicLinq

DynamicLinq你可以这样做:

IQueryable query = context.YourTable;
var groups = query.GroupBy("new (Field1, Field2)");

我正在重读你的问题...

I want to be able to identify fields in the group by keys with strong names in select part like query.Select(x => new { x.Key.DepartmentID, x.Key.SkillID });

你不能。 GroupBy一般会返回 IGrouping<TKey, TSource> . TKey是动态的(因为你基于字符串构建它),所以你不能“提取”它并将它传递给编译器,所以你不能使用强名称进行选择。

有一个异常(exception):如果您知道 GroupBy TKey 的类型和编号,那么就可以做一些事情。所以,你给了我们:

String[] fields = { "DepartmentID", "SkillID" };

如果您总是有两个 int 那么您可以使用以下方式进行查询:

.Cast<IGrouping<Tuple<int, int>, Person>>()
.Select(x => new { x.Key.DepartmentID, x.Key.SkillID });

请注意,正如我在评论中所写,您的 GroupBy将在客户端执行,以及 GroupBy 之后的所有内容将在客户端执行(其中客户端 == 你的程序所在的位置 vs sql 端 == 你的 sql 服务器所在的位置)!

DynamicLinq 解决执行查询sql端而不是客户端的问题,但是won't解决强命名与弱命名的问题(在 DynamicLinq 之后,您可以:A)使用 .Cast<>()方法或 B) 返回 dynamic对象/IEnumerable<dynamic> )

关于c# - 在 Group By 中使用表达式树后无法选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29120249/

相关文章:

linq-to-sql - 使用 Linq to SQL 和 Sql Reporting Services

c# - 如何在 Linq-to-SQL 实体类中创建自定义属性?

c# - 数据上下文应该是静态的吗?

c# - C# 自动关闭消息框

c# - "GetBy"Web API中的方法

c# - LINQ to SQL 连接中的 DefaultIfEmpty() 导致重复

c# - 如何使用 LINQ 将 .csv 文件读入数组

c# - CheckBoxFor 的 MVC 3 自定义 ValidationAttribute 在客户端触发两次

vb.net - 在特定值 vb.net 上使用 linq 选择列表中的计数

c# - 如何使用 LINQ 查询此分层数据?