Entity Framework 列表中的动态 Where 子句<object>
Entity Framework Dynamic Where Clause from List<object>
在互联网上搜索之后,我一直无法找到可以开始工作的解决方案。我正在尝试使用动态 linq 使用户能够从 windows 表单构建自定义查询。为了保存每个 where 子句,我构建了一个名为 WhereClause 的对象:
public class WhereClause
{
public int id { get; set; }
public string ColumnName { get; set; }
public string Operator { get; set; }
public string OperatorSymbol { get; set; }
public object Value { get; set; }
public string AndOr { get; set; }
public string AndOrSymbol { get; set; }
}
大多数是不言自明的,但是运算符和运算符符号之间的区别在于运算符将 "Equals" 或 "Greater Than" 存储到运算符符号为“==”和“>”的位置分别。 AndOR 以类似的方式工作。
然后当用户构建 where 子句时,会创建一个新的 WhereClause 对象并将其添加到 List<WhereClause>
当需要 运行 查询时,我正在使用 entity framework 和 linq 来构建查询。
我想做这样的事情:
List<WhereClause> wheres; //populated via parameter in the encapsulating method.
DataContext db = new DataContext();
var query = from d in db.Database select d;
string whereClause = "";
foreach(WhereClause where in wheres){
whereClause = whereClause + String.Format(" {0} {1} {2} {3}", where.ColumnName, where.OperatorSymbol, where.Value, where.AndOrSymbol);
query.Where(whereClause);
}
我尝试了各种构建 where 子句的方法,包括使用 where(predicate, params)
和使用 "@1"
格式化谓词,但还没有找到正确的方法。
这是上下文的查询构建器的样子..
所以现在我转向你们寻求帮助..
您需要将您的 WhereClause
对象翻译成 Expression
,然后您可以将其用作 where 查询。举个例子:
Type yourType = typeof(YourGeneric);
ParameterExpression pe = Expression.Parameter(yourType , "x");
Expression left = Expression.Property(pe, yourType.GetProperty(whereClause.ColumnName));
Expression right = Expression.Constant(whereClause.Value, typeof(int));
Expression result = Expression.Equal(left, right);
这是一个比较 int
属性 的例子。您需要一些 if(或 switch)来了解 属性 类型以及您需要进行的比较类型。
if (whereClause.Operator == "Greater Than") {
result = Expression.GreaterThan(left, right);
}
当您以这种方式完成使用 Expression
时:
context.Set<YourGeneric>().Where(result);
我建议使用泛型(如果可能的话)来简化代码和工作。
您还可以连接更多表达式:
Expression result4 = Expression.AndAlso(result1, result2);
Expression finalRes = Expression.Or(result3, result4);
在互联网上搜索之后,我一直无法找到可以开始工作的解决方案。我正在尝试使用动态 linq 使用户能够从 windows 表单构建自定义查询。为了保存每个 where 子句,我构建了一个名为 WhereClause 的对象:
public class WhereClause
{
public int id { get; set; }
public string ColumnName { get; set; }
public string Operator { get; set; }
public string OperatorSymbol { get; set; }
public object Value { get; set; }
public string AndOr { get; set; }
public string AndOrSymbol { get; set; }
}
大多数是不言自明的,但是运算符和运算符符号之间的区别在于运算符将 "Equals" 或 "Greater Than" 存储到运算符符号为“==”和“>”的位置分别。 AndOR 以类似的方式工作。
然后当用户构建 where 子句时,会创建一个新的 WhereClause 对象并将其添加到 List<WhereClause>
当需要 运行 查询时,我正在使用 entity framework 和 linq 来构建查询。
我想做这样的事情:
List<WhereClause> wheres; //populated via parameter in the encapsulating method.
DataContext db = new DataContext();
var query = from d in db.Database select d;
string whereClause = "";
foreach(WhereClause where in wheres){
whereClause = whereClause + String.Format(" {0} {1} {2} {3}", where.ColumnName, where.OperatorSymbol, where.Value, where.AndOrSymbol);
query.Where(whereClause);
}
我尝试了各种构建 where 子句的方法,包括使用 where(predicate, params)
和使用 "@1"
格式化谓词,但还没有找到正确的方法。
这是上下文的查询构建器的样子..
所以现在我转向你们寻求帮助..
您需要将您的 WhereClause
对象翻译成 Expression
,然后您可以将其用作 where 查询。举个例子:
Type yourType = typeof(YourGeneric);
ParameterExpression pe = Expression.Parameter(yourType , "x");
Expression left = Expression.Property(pe, yourType.GetProperty(whereClause.ColumnName));
Expression right = Expression.Constant(whereClause.Value, typeof(int));
Expression result = Expression.Equal(left, right);
这是一个比较 int
属性 的例子。您需要一些 if(或 switch)来了解 属性 类型以及您需要进行的比较类型。
if (whereClause.Operator == "Greater Than") {
result = Expression.GreaterThan(left, right);
}
当您以这种方式完成使用 Expression
时:
context.Set<YourGeneric>().Where(result);
我建议使用泛型(如果可能的话)来简化代码和工作。 您还可以连接更多表达式:
Expression result4 = Expression.AndAlso(result1, result2);
Expression finalRes = Expression.Or(result3, result4);