使用表达式树的动态查询 [英] dynamic query using expression tree

查看:80
本文介绍了使用表达式树的动态查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a form in which the user will choose the following from dropdown lists:

  table_name
  columnName_to_sort_by
  columnName_to_search_in

用户应在文本框中输入Search_text

The user shall enter Search_text in a text box

该表格应从许多表格中提取数据.我想避免编写排序并搜索每个表的每个字段.这就是为什么我要使用表达式树.我想动态地建立查询.

The form shall draw data from many tables. I want to avoid writing the sort and search for every field for each of the tables. This is why I want to use expression trees. I want to build the query dynamically.

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

I want to write a generic method that will generate the expression tree for the select, where and orderby methods, depending on user input. I can use System.Reflection to get the Type that is being queried (all my tables are types - I am using LinqToSql).

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

I do not know how to form the expression trees.

这是我到目前为止所拥有的:

Here's what I have so far:

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?

How can I implement select, sort and orderby dynamically using expression trees?

推荐答案

您所拥有的很近.当您询问"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

这篇关于使用表达式树的动态查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆