且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用表达式树的动态查询

更新时间:2023-02-16 13:01:02

您所拥有的很近.当您询问"WHAT_SHOULD_BE_HERE"时,您很好奇要使用哪种表达式来表示OrderBy的源"参数,当用作扩展方法时,通常从操作数中隐含该参数.您需要做的是更改示例以对IQueryable进行操作,并且需要接受它作为输入参数.另外,将WHAT_SHOULD_BE_HERE占位符替换为"list.Expression",如下所示.

What you have is close. Where you ask, "WHAT_SHOULD_BE_HERE", you are curious what expression to use to indicate the "source" parameter for OrderBy, which is usually implied from the operand when used as an extension method. What you need to do is change your sample to operate on IQueryable, and you need to accept that as an input parameter. Also, replace your WHAT_SHOULD_BE_HERE placeholder with "list.Expression" as shown below.

private static IEnumerable<T> GetSortedData<T>(IQueryable<T> list, string sortColumnName) 
{ 
    var type = typeof(T); 
    var property = type.GetProperty(sortColumnName); 
    var parameter = Expression.Parameter(type, "p"); 
    var propertyAccess = Expression.Property(parameter, property); 
    var orderByExp = Expression.Lambda(propertyAccess, parameter); 
    MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy", new[] { type, property.PropertyType }, list.Expression, Expression.Quote(orderByExp)); 
    return (IEnumerable<T>)Expression.Lambda(resultExp).Compile().DynamicInvoke(); 
} 

我使用以下代码对此进行了测试:

I tested this with the following code:

static void Main(string[] args)
{
    var list = new List<Person>(new[] 
    { 
        new Person { FirstName = "John" }, 
        new Person { FirstName = "Jane" }
    }).AsQueryable();

    foreach (var o in GetSortedData(list, "FirstName")) 
        Console.WriteLine(o.FirstName);
}

public class Person
{
    public string FirstName { get; set; }
}

打印出的内容:

Jane
John