我有一个表单,用户将从下拉列表中选择以下内容:
table_name
columnName_to_sort_by
columnName_to_search_in
用户应在文本框中输入Search_text
表格应从许多表格中提取数据。我想避免编写排序并搜索每个表的每个字段。这就是我想使用表达式树的原因。我想动态构建查询。
我想编写一个泛型方法,它将为select
, where
和orderby
方法生成表达式树,具体取决于用户输入。我可以使用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();
}
如何使用表达式树动态实现select
, sort
和orderby
?
你所拥有的是亲密的。如果你问“WHAT_SHOULD_BE_HERE”,你很好奇用什么表达式来表示OrderBy的“source”参数,当用作扩展方法时,它通常隐含在操作数中。您需要做的是更改样本以对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