我正在尝试包含相关实体,并对它们进行排序。
如果您知道实体和相关项,它可以像下面这样简单:
context.Set<Item>().Include(x => x.SubItems.OrderBy(x => x.Name));现在我尝试动态地复制上面的场景,结果应该是这样的:
{[Microsoft.EntityFrameworkCore.Query.QueryRootExpression].Include(x => x.SubItems.OrderBy(y => y.Name))}但我得到的最接近的结果是:
{[Microsoft.EntityFrameworkCore.Query.QueryRootExpression].Include(x => x.SubItems).OrderBy(y => y.Name)}我在这里做错了什么?下面是我的代码:
private static IQueryable<T> IncludeNaviagations<T>(DbContext context, IQueryable<T> queryable)
{
var type = typeof(T);
foreach (var nav in context.Model.FindEntityType(typeof(T)).GetNavigations())
{
var method = IncludeMethodInfo.MakeGenericMethod(new[] { type, type.GetProperty(nav.Name).PropertyType });
var includeParam = Expression.Parameter(type, "x");
var includeProperty = Expression.Property(includeParam, nav.Name);
var includeLambda = Expression.Lambda(includeProperty, includeParam);
var include = Expression.Call(instance: null, method: IncludeMethodInfo.MakeGenericMethod(type, nav.PropertyInfo.PropertyType), arguments: new[] { queryable.Expression, Expression.Quote(includeLambda) });
var orderColumn = "Name";
var property = type.GetProperty(orderColumn);
var param = Expression.Parameter(type, "y");
var propName = Expression.Property(param, orderColumn);
var sort = Expression.Lambda(propName, param);
var result = Expression.Call(typeof(Queryable), "OrderBy", new[] { type, sort.ReturnType }, include, Expression.Quote(sort));
queryable = queryable.Provider.CreateQuery<T>(result);
}
return queryable;
}PS。上面的方法将进行一点调整,以递归地执行includes。
发布于 2021-01-14 23:49:00
在花了相当多的时间之后,我让它工作了,下面是一个拼凑起来的解决方案:
OrderByMethodInfo = typeof(Enumerable).GetMethods().First(x => x.Name == "OrderBy" && x.GetParameters().Length == 2);
var orderColumnType = subType.GetProperty(orderColumn).PropertyType;
orderByMethod = orderByMethod.MakeGenericMethod(subType, orderColumnType);
var includeParam = Expression.Parameter(nav.ParentType, "x");
var includeProperty = Expression.Property(includeParam, nav.Name);
var property = nav.ParentType.GetProperty(orderColumn);
var param = Expression.Parameter(subType, "y");
var propName = Expression.Property(param, orderColumn);
var sort = Expression.Lambda(propName, param);
var order = Expression.Call(orderByMethod, includeProperty, sort);
var orderLambda = Expression.Lambda(order, Expression.Parameter(nav.ParentType, "x"));
var orderQuote = Expression.Quote(orderLambda);
var includeMethod = IncludeMethodInfo.MakeGenericMethod(nav.ParentType, typeof(IOrderedEnumerable<>).MakeGenericType(subType));
result = Expression.Call(instance: null, method: includeMethod, arguments: new[] { queryable.Expression, orderQuote });
queryable.Provider.CreateQuery<object>(result);https://stackoverflow.com/questions/65673779
复制相似问题