Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态lambda表达式(OrderBy)和可为空的属性类型_C#_Linq_Entity Framework_Lambda_Expression Trees - Fatal编程技术网

C# 动态lambda表达式(OrderBy)和可为空的属性类型

C# 动态lambda表达式(OrderBy)和可为空的属性类型,c#,linq,entity-framework,lambda,expression-trees,C#,Linq,Entity Framework,Lambda,Expression Trees,我试图动态创建表达式,通过实体框架对数据库中的数据进行排序。但我遇到了一个问题,无法克服它。也许让我解释一下我想做什么。我的目标是创建如下表达式: x => x.Property 其中“Property”是我要动态指定的属性的名称 现在,让我们转到类,它表示数据库中的表(我简化了它以使事情更清楚): 这是我的代码,我正在尝试创建前面描述的表达式: // Db is EntityFramework context IQueryable<MyModelClass> list =

我试图动态创建表达式,通过实体框架对数据库中的数据进行排序。但我遇到了一个问题,无法克服它。也许让我解释一下我想做什么。我的目标是创建如下表达式:

x => x.Property
其中“Property”是我要动态指定的属性的名称

现在,让我们转到类,它表示数据库中的表(我简化了它以使事情更清楚):

这是我的代码,我正在尝试创建前面描述的表达式:

// Db is EntityFramework context
IQueryable<MyModelClass> list = Db.MyModels.Select(x => x);

// x =>
var argument = Expression.Parameter(list.ElementType, "x");

// x.MyNullableDecimalProperty
var propertyToOrder = Expression.Property(argument, "MyNullableDecimalProperty");

// x => x.MyNullableDecimalProperty
var finalExpression = Expression.Call(
    typeof (Queryable),
    "OrderBy",
    new[] { list.ElementType, typeof(IComparable) },
    list.Expression,
    Expression.Lambda<Func<MyModelClass, IComparable>>(propertyToOrder, argument));

list = list.Provider.CreateQuery<MyModelClass>(finalExpression);
//数据库是EntityFramework上下文
IQueryable list=Db.MyModels.Select(x=>x);
//x=>
var参数=Expression.Parameter(list.ElementType,“x”);
//x.MyNullableDecimalProperty
var propertyToOrder=Expression.Property(参数“MyNullableDecimalProperty”);
//x=>x.MyNullableDecimalProperty
var finalExpression=Expression.Call(
类型(可查询),
“订购人”,
新[]{list.ElementType,typeof(IComparable)},
列表。表达式,
Lambda(propertyToOrder,argument));
list=list.Provider.CreateQuery(finalExpression);
问题出现在第4条语句(var finalExpression=Expression.Call(…)中)。我得到一个例外:

“System.Nullable`1[System.Decimal]”类型的表达式不能用于返回类型“System.IComparable”

据我所知,问题在于我使用“IComparable”类型,其中“MyNullableDecimalProperty”可为null,而Nullable不使用IComparable接口。当我按“MyLongProperty”排序或替换“IComparable”时,不会引发异常

所以我的问题是:

  • 我应该使用什么类型使其与任何可为null的属性一起工作

  • 是否可以使用一种类型,并且它将处理所有属性,无论它们是可为null的还是不可为null的


  • 注意:我知道我可以使用ex.Dynamic Linq库,但我对这个解决方案不感兴趣-我想学习如何在不使用第三方库的情况下克服它。

    您不需要指定IComparable部分,也可以使用Queryable.OrderBy/OrderByDescending方法来帮助您:

    IQueryable<TSource> source = .....
    var sourceType = typeof(TSource);
    var parameter = Expression.Parameter(sourceType, "item");
    var propertyInfo = GetProperty(sourceType, propertyName);
    var orderByProperty = Expression.Property(parameter, propertyInfo);
    orderBy = Expression.Lambda(orderByProperty, new[] { parameter });
    
    return Queryable.OrderBy(source, (dynamic)orderBy)
    
    IQueryable源=。。。。。
    var sourceType=typeof(TSource);
    var参数=Expression.parameter(sourceType,“item”);
    var propertyInfo=GetProperty(sourceType,propertyName);
    var orderByProperty=Expression.Property(参数,propertyInfo);
    orderBy=Expression.Lambda(orderByProperty,新[]{parameter});
    返回Queryable.OrderBy(源,(动态)OrderBy)
    

    试一试,看看进展如何,我很确定这对本机类型和可空类型都有效。

    没有理由使用
    IComparable
    。事实上,许多可比较的类型没有实现
    IComparable
    。只需使用所传递内容的运行时类型:

    var finalExpression = Expression.Call(
        typeof (Queryable),
        "OrderBy",
        new[] { list.ElementType, propertyToOrder.Type },
        list.Expression,
        Expression.Lambda(propertyToOrder, new [] { argument }));
    

    如果为
    MyModelClass
    实现
    IComperable
    ,或者将
    MyNullableDecimalProperty
    封装到实现
    IComperable
    的类中,该怎么办。
    var finalExpression = Expression.Call(
        typeof (Queryable),
        "OrderBy",
        new[] { list.ElementType, propertyToOrder.Type },
        list.Expression,
        Expression.Lambda(propertyToOrder, new [] { argument }));