首页 > 解决方案 > C# 表达式按关键字段对通用查询进行排序

问题描述

我有一个通用方法,我想IQueryable<T>按其键字段对它进行排序(可以安全地假设只有一个)。因此:

void DoStuff<T>(...) 
{
   IQueryable<T> queryable = ... // given
   PropertyInfo keyField = ... // given
   var sortedQueryable = queryable.OrderBy(<some expression here>);
   ...
}

如何定义一个Expression将返回的keyField属性,T以便它可以工作?

标签: c#linqlinq-expressions

解决方案


这并不太难,但是您需要调用OrderBywith 反射,因为您提前不知道键字段的类型。因此,鉴于您已经显示的代码,您将执行以下操作:

// Build up the property expression to pass into the OrderBy method
var parameterExp = Expression.Parameter(typeof(T), "x");
var propertyExp = Expression.Property(parameterExp, keyField);
var orderByExp = Expression.Lambda(propertyExp, parameterExp);

// Note here you can output "orderByExp.ToString()" which will give you this:
//  x => x.NameOfProperty

// Now call the OrderBy via reflection, you can decide here if you want 
// "OrderBy" or "OrderByDescending"
var orderByMethodGeneric = typeof(Queryable)
    .GetMethods()
    .Single(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);

var orderByMethod = orderByMethodGeneric.MakeGenericMethod(typeof(T), propertyExp.Type);

// Get the result
var sortedQueryable = (IQueryable<T>)orderByMethod
    .Invoke(null, new object[] { queryable, orderByExp });

推荐阅读