实体框架Dynamic List from List <object>

时间:2018-05-02 14:08:24

标签: c# linq-to-sql dynamic-linq

在鞭打互联网之后,我无法找到可以开始工作的解决方案。我试图使用动态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; }
}

大多数都是自我解释的,但操作员和操作员符号之间的区别在于操作员将存储&#34;等于&#34;或者&#34;大于&#34;操作符号将在哪里&#34; ==&#34;和&#34;&gt;&#34;分别。 AndOR以类似的方式工作。

然后,当用户构建where子句时,会创建一个新的WhereClause对象并将其添加到List<WhereClause>

当运行查询时,我正在使用实体框架和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"格式化谓词但未找到正确的方法。

以下是上下文查询构建器的外观。 enter image description here

所以现在我转向你们寻求帮助..

1 个答案:

答案 0 :(得分:1)

您需要将WhereClause对象翻译为Expression,然后您可以将其用作查询位置。这是一个例子:

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