【问题标题】:dynamic query using expression tree使用表达式树的动态查询
【发布时间】:2010-06-24 17:22:13
【问题描述】:

我有一个表单,用户可以在其中从下拉列表中选择以下内容:

  table_name
  columnName_to_sort_by
  columnName_to_search_in

用户应在文本框中输入Search_text

表单应从许多表中提取数据。我想避免为每个表编写排序和搜索每个字段。这就是我想使用表达式树的原因。我想动态构建查询。

我想编写一个通用方法,根据用户输入为selectwhereorderby 方法生成表达式树。我可以使用System.Reflection 来获取正在查询的Type(我所有的表都是类型-我正在使用LinqToSql)。

我不知道如何形成表达式树。

这是我目前所拥有的:

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

如何使用表达式树动态实现selectsortorderby

【问题讨论】:

    标签: c# expression-trees dynamic-linq


    【解决方案1】:

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

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

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

    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
    

    【讨论】:

    • 在排序方式中有多个列的任何方式
    【解决方案2】:

    Order by 遇到了同样的错误。

    我查看了Call 方法,发现我缺少参数--list.Expression,其中列表是您的IQuerable

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 1970-01-01
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多