根据用户选择生成LinqToEntities Where语句
本文关键字:LinqToEntities Where 语句 用户 选择 | 更新日期: 2023-09-27 18:23:48
我有一个用户界面,用户可以在其中为该列选择网格列(如年龄)和运算符(小于、等于或大于)。
然后根据选择过滤网格数据。
我有以下类,它们是从来自客户端的JSON反序列化而来的。
/// <summary>
/// Filter for reducing grid results
/// </summary>
public class Filter
{
/// <summary>
/// Name of the column
/// </summary>
public string name;
public string value;
public int @operator { private get; set; }
public Operator Operator()
{
return (Operator) @operator;
}
}
public enum Operator
{
None = -1,
LesserThan = 0,
Equals = 1,
GreaterThan = 2
}
由于为过滤动态添加新列的特性,我想创建访问数据的通用解决方案。
我想避免像这样的大量if/switch语句
switch(columnName)
{
case "age":
{
if(operator == Operator.LesserThan)
{
query = entities.Where(o => o.Age < age);
}
else if (operator == Operator.GreaterThan)
{
query = entities.Where(o => o.Age > age);
}
etc.
break;
}
etc.
}
有什么想法可以为这个问题创建更通用的解决方案吗?
更新似乎有很多方法可以实现比十亿if语句更清洁的解决方案。现在我只需要比较不同的解决方案。
您可以使用Dynamic LINQ来动态创建查询
编辑:
动态LINQ查询的一个示例如下,假设网格中的列名与实体中的字段名相同:
string queryString;
queryString = columnName;
if(operator == Operator.LesserThan)
{
queryString += " < ";
}
else if (operator == Operator.GreaterThan)
{
queryString += " > ";
}
etc.
queryString += age.ToString(); // Or use bind variables, haven't tried that myself in dynamic LINQ
query = entites.Where(queryString);
您可以使用PredicateBuilder根据需要动态构建linq查询。这将帮助您轻松构建linq表达式。至于会随着时间的推移而增长的丑陋切换,我建议,如果"name"总是与linq表达式中的一个属性相关(例如"age"-->.age),那么你应该能够通过一些反射代码来获得它,所以你要检查"name"是否与同名的属性相关,如果是,则为其构建一个过滤器。
HTH
您可以将根据输入组成的System.Linq.Expressions.Expression对象传递给Where方法。以下是如何组合谓词表达式以与EF或Linq2Sql一起使用的示例:动态合成表达式谓词
您可以使用ESQL而不仅仅是LINQ:
Context.Entities
.Where("it.Age > @Age", new[] { new ObjectParameter("Age", age } );
您可以很容易地根据您的过滤器为您的条件生成字符串表示。
如果您需要的话,下面是对ESQL的完整引用。
您可以使用反射代码,例如:
String columName; //your dynamic columnName
if(operator == Operator.LesserThan)
{
query = entities.Where(o => o.GetType().GetProperty(columName).GetValue(o, null) <columName);
}
else if (operator == Operator.GreaterThan)
{
etc.
}