向 IQueryable 添加动态 GroupBy 表达式

huangapple go评论64阅读模式
英文:

Adding a dynamic GroupBy expression to an IQueryable

问题

我想将动态的 GroupBy 表达式传递给一个 IQueryable。我已经在使用 Where 子句时做了类似的事情,它可以正常工作。

Group by 的目的是允许我提取每个组中每个记录的最新版本。例如:

object MyMethod(Expression<Func<MyObj,int>> whereExpr = null, 
			  Expression<Func<MyObj,int>> groupByExpr = null)
{
    var query = DbSet.Where(x => x.IsArchived == false);

	if (whereExpr != null) {
		query = query.Where(whereExpr); // 这部分可以工作
	}

	if (groupByExpr != null) {
		query = query.GroupBy(groupByExpr).Select(g => g.OrderByDescending(x => x.CreatedDate).FirstOrDefault()).AsQueryable(); // 这部分抛出了客户端错误
	}
	
	return new GridDevExtremeDataSource<TEntity>(query);
}

然后可以这样调用:

var obj = MyMethod(whereExpr: x => x.Id > 100, groupByExpr: x => x.CategoryId)

这会抛出一个客户端错误:
> Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
>  ---> System.InvalidOperationException: Nullable object must have a value.

英文:

I want to pass a dynamic GroupBy expression into an IQueryable. I'm already doing something similar with a Where clause that is working OK.

The purpose of the group by is then to allow my to extract just the most recent version of each record in each respective group. For example:

object MyMethod(Expression<Func<MyObj,int>> whereExpr = null, 
			  Expression<Func<MyObj,int>> groupByExpr = null)
{
    var query = DbSet.Where(x => x.IsArchived == false);


	if (whereExpr != null) {
		query = query.Where(whereExpr); // this is working
	}

	if (groupByExpr != null) {
		query = query.GroupBy(groupByExpr).Select(g => g.OrderByDescending(x => x.CreatedDate).FirstOrDefault()).AsQueryable(); // this is throwing a client side error
	}
	
	return new GridDevExtremeDataSource<TEntity>(query);
}

Then called with something like

var obj = MyMethod(whereExpr: x => x.Id > 100, groupByExpr: x => x.CategoryId)

This is throwing a client side error:
> Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
>  ---> System.InvalidOperationException: Nullable object must have a value.

答案1

得分: 1

实际上,您正在尝试从组中获取最新的项目。看起来 EF Core,至少在版本 7 中,对这种查询有限制。

我已经为类似的问题准备了另一个答案,并实现了自定义 DistinctBy 扩展,模拟了 EF Core 应该为检索分组项目的最后一条记录所做的操作。

因此,使用此函数的问题行应该如下所示:

query = query.DistinctBy(groupByExpr, x => x.CreatedDate);
英文:

Actually you are trying to get latest item from the group. Looks like EF Core, at least up to version 7, has limitation in such queries.

I have prepared another answer for similar problem and implemented custom DistinctBy extension implementation which mimic what EF Core should do for retrieving last record of grouped items.

So, you problematic line with this function should looks like:

query = query.DistinctBy(groupByExpr, x => x.CreatedDate);

huangapple
  • 本文由 发表于 2023年7月28日 01:16:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76782091.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定