EF Core动态包含和订购

工作

我正在尝试包括相关实体并对其进行排序。

如果您知道实体和相关项目,则可以很简单:

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。上面的方法将被微调以递归方式进行包含。

工作

在花了很多时间后,我开始工作了,这里是一个拼凑的解决方案:

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);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章