在MemberExpression上连接一个MethodCallExpression

问题描述 投票:2回答:1

我希望使用表达式树创建以下Linq表达式:

var result2 = soldiers.OrderByDescending(soldier => soldier.Ranks.OrderBy(r=> r.Date).FirstOrDefault().Date).ToArray() ;

模型列在问题的最后

我试着做以下事情:

ParameterExpression pe = Expression.Parameter(typeof(Soldier), "soldier");

// e.g soldier.ranks
MemberExpression rank = Expression.Property(pe, "ranks");

ParameterExpression nestedParams = Expression.Parameter(typeof(Rank), "rank");

var dateProperty = typeof(Rank).GetProperty("Date");

// e.g rank.Date
MemberExpression nestedExpression= Expression.MakeMemberAccess(nestedParams, dateProperty);

// e.g rank => rank.date
var orderByExp = Expression.Lambda<Func<Rank, DateTime?>>(nestedExpression, nestedParams);

MethodCallExpression orderByCallExpression2 = Expression.Call(
typeof(Queryable),
"OrderByDescending",
 new Type[] { typeof(Rank), typeof(DateTime?) },
 rank, ***// i suspect the problem is in this line #110***
 orderByExp);

但是抛出了以下错误:

System.InvalidOperationException: 'No generic method 'OrderByDescending' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. '

正如我在代码的注释中写的那样,我怀疑问题出现在第110行。我试图在soldier.ranks属性上连接orderBy方法。但也许因为`soldier.ranks是MemberExpression而不是MethodCallExpression或Queryable,我无法执行该操作。

我使用两个链接作为参考,但可以找到任何类似于我的问题。 * qazxsw poi

* https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/how-to-use-expression-trees-to-build-dynamic-queries

楷模:

https://stackoverflow.com/a/11337472/10950549

谢谢,

c# linq lambda expression-trees
1个回答
3
投票

我怀疑问题是因为110行而发生的

public class Soldier
{
    public Rank Rank {
        get {
            return this.Ranks.OrderByDescending(m => m.Date).FirstOrDefault();
        }
    }

    public ICollection<Rank> Ranks { get; set; }
}

public class Rank
{
    public int Id { get; set; }

    public DateTime? Date { get; set; }
}

不,问题是上面的MethodCallExpression orderByCallExpression2 = Expression.Call( typeof(Queryable), "OrderByDescending", new Type[] { typeof(Rank), typeof(DateTime?) }, rank, ***// i suspect the problem is in this line #110*** orderByExp); 3行:

Queryable

typeof(Queryable), 是什么类型的表达式(成员,方法调用等)并不重要,重要的是该表达式的结果类型(即rank)。 Expression.Type的类型是soldier.Ranks - 绝对不是ICollection<Rank>,因此例外。

但正如我们所知,IQueryable<Rank>继承(是)ICollection<T>,因此IEnumerable<T>实际上是对oldier.Ranks.OrderBy而不是Enumerable.OrderBy

话虽如此,只需将Queryable.OrderBy更改为上述行中的Queryable,这个特殊问题就会得到解决。

© www.soinside.com 2019 - 2024. All rights reserved.