首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EF核心动态包含和排序

EF核心动态包含和排序
EN

Stack Overflow用户
提问于 2021-01-12 04:06:08
回答 1查看 248关注 0票数 0

我正在尝试包含相关实体,并对它们进行排序。

如果您知道实体和相关项,它可以像下面这样简单:

代码语言:javascript
复制
context.Set<Item>().Include(x => x.SubItems.OrderBy(x => x.Name));

现在我尝试动态地复制上面的场景,结果应该是这样的:

代码语言:javascript
复制
{[Microsoft.EntityFrameworkCore.Query.QueryRootExpression].Include(x => x.SubItems.OrderBy(y => y.Name))}

但我得到的最接近的结果是:

代码语言:javascript
复制
{[Microsoft.EntityFrameworkCore.Query.QueryRootExpression].Include(x => x.SubItems).OrderBy(y => y.Name)}

我在这里做错了什么?下面是我的代码:

代码语言:javascript
复制
    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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-14 23:49:00

在花了相当多的时间之后,我让它工作了,下面是一个拼凑起来的解决方案:

代码语言:javascript
复制
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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65673779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档