我希望使用表达式树创建以下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,所以我无法执行该操作。

我将两个链接都用作参考,但是可以找到解决我问题的任何模拟方法。
* 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

楷模:

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


谢谢,

最佳答案

我怀疑问题是由于第110行而发生


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


不,问题在于上面的Queryable 3行:

typeof(Queryable),


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

但是我们知道,ICollection<T>继承(是)IEnumerable<T>,因此oldier.Ranks.OrderBy实际上是对Enumerable.OrderBy而不是Queryable.OrderBy的调用。

话虽如此,只需在上述行中将Queryable更改为Enumerable即可解决此特定问题。

关于c# - 将MethodCallExpression连接到MemberExpression,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54873870/

10-10 14:36