实体框架按字符串sql过滤数据

Con*_*ver 14 sql linq sql-server entity-framework linq-expressions

我在我的表中存储了一些过滤数据.让我更清楚一点:我想将一些where子句及其值存储在数据库中,并在我想从数据库中检索数据时使用它们.

例如,考虑一个people表(实体集)和另一个表中的一些过滤器:

"age" , "> 70"
"gender" , "= male"
Run Code Online (Sandbox Code Playgroud)

现在,当我从people表中检索数据时,我想让这些过滤器过滤我的数据.

我知道我可以生成一个SQL查询作为字符串并执行它,但在EF,LINQ中还有其他更好的方法吗?

Tah*_*ooy 8

一种解决方案是使用Dynamic Linq Library,使用此库可以:

filterTable = //some code to retrive it
var whereClause = string.Join(" AND ", filterTable.Select(x=> x.Left + x.Right));
var result = context.People.Where(whereClause).ToList(); 
Run Code Online (Sandbox Code Playgroud)

假设过滤器表包含列Left,Right并且您希望按以下方式连接过滤器AND.

我的建议是在过滤器表中包含更多细节,例如将操作符与操作数分开,并添加一个确定连接的列,And或者OR一个列,用于确定连接该连接的另一行.如果要处理更复杂的查询,则需要树结构(A and B)Or(C and D).

另一种解决方案是从过滤表构建表达式树.这是一个简单的例子:

var arg = Expression.Parameter(typeof(People));
Expression whereClause;
for(var row in filterTable)
{
     Expression rowClause;
     var left = Expression.PropertyOrField(arg, row.PropertyName);
     //here a type cast is needed for example
     //var right = Expression.Constant(int.Parse(row.Right));
     var right = Expression.Constant(row.Right, left.Member.MemberType);
     switch(row.Operator)
     {
          case "=":
              rowClause = Expression.Equal(left, right);
          break;
          case ">":
              rowClause = Expression.GreaterThan(left, right);
          break;
          case ">=":
              rowClause = Expression.GreaterThanOrEqual(left, right);
          break;
      }
      if(whereClause == null)
      {
          whereClause = rowClause;
      }
      else
      {
          whereClause = Expression.AndAlso(whereClause, rowClause);
      }
}
var lambda = Expression.Lambda<Func<People, bool>>(whereClause, arg);
context.People.Where(lambda);
Run Code Online (Sandbox Code Playgroud)

这是一个非常简化的示例,您应该进行许多验证类型转换和...以使其适用于所有类型的查询.

  • 您的示例将极大地帮助OP可视化需要完成的工作.让我为感兴趣的读者提出一些建议,让他们找出下一步:考虑[解释器模式](https://en.wikipedia.org/wiki/Interpreter_pattern)或[访客模式](https://en.wikipedia .org/wiki/Visitor_pattern)([比较](http://www.researchgate.net/profile/Tijs_Van_der_Storm/publication/220878226_A_Case_of_Visitor_versus_Interpreter_Pattern/links/09e4150981f71beda3000000.pdf)).这通常会使设计更容易维护,但当然这个想法是一样的. (3认同)