[英]Dynamically Build EF Query
I am working on a dynamic query solution for a project.我正在为一个项目开发动态查询解决方案。 I want to avoid a bunch of if/else or switch statements just to change the [DynamicFieldName] part of these queries.
我想避免一堆 if/else 或 switch 语句只是为了更改这些查询的 [DynamicFieldName] 部分。
IQueryable<MyDataType> allItems = (from item in Context.MyDataTypes select item);
foreach (QueryEntry currentEntry in query.Fields)
{
allItems = allItems.Where(item => item.[DynamicFieldName] == currentEntry.Value);
}
The user gets to build the query via the GUI that has a variable number of fields.用户可以通过具有可变数量字段的 GUI 来构建查询。 In the end, they will also have a variety of comparisons to choose from (Less than, greater than, equal, contains, etc.) that vary by data type.
最后,它们还将有多种比较可供选择(小于、大于、等于、包含等),这些比较因数据类型而异。
What method can I use to build this programatically in a nice reusable fashion?我可以使用什么方法以一种很好的可重用方式以编程方式构建它?
Have a look at this code:看看这个代码:
public static class CustomQueryBuilder
{
//todo: add more operations
public enum Operator
{
Equal = 0,
GreaterThan = 1,
LesserThan = 2
}
public static IQueryable<T> Where<T>(this IQueryable<T> query, string property, Operator operation, object value)
{
//it's an item which property we are referring to
ParameterExpression parameter = Expression.Parameter(typeof(T));
//this stands for "item.property"
Expression prop = Expression.Property(parameter, property);
//wrapping our value to use it in lambda
ConstantExpression constant = Expression.Constant(value);
Expression expression;
//creating the operation
//todo: add more cases
switch (operation)
{
case Operator.Equal:
expression = Expression.Equal(prop, constant);
break;
case Operator.GreaterThan:
expression = Expression.GreaterThan(prop, constant);
break;
case Operator.LesserThan:
expression = Expression.LessThan(prop, constant);
break;
default:
throw new ArgumentException("Invalid operation specified");
}
//create lambda ready to use in queries
var lambda = Expression.Lambda<Func<T, bool>>(expression, parameter);
return query.Where(lambda);
}
}
Usage用法
var users = context
.Users
.Where("Name", CustomQueryBuilder.Operator.Equal, "User")
.ToList();
Which is equal to这等于
var users = context
.Users
.Where(u => u.Name == "User")
.ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.