2012-02-08 80 views
1

我有用户界面,用户可以选择该列的网格列(如年龄)和运算符(小于,等于或大于)。生成LinqToEntities其中声明取决于用户选择

然后根据选择过滤网格数据。

我有一个从客户端来的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 
} 

由于性质动态添加新的列过滤我想创建通用的解决方案来访问数据。

我想如果有巨量/开关之类的语句

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. 
} 

任何想法如何创建问题更加通用的解决方案避免?

更新 看来,有许多方法可以完成清洁解决方案,而不是10亿条语句。现在我只需要比较不同的解决方案。

回答

1

你可以使用Dynamic LINQ动态创建查询

编辑:

动态LINQ查询的一个例子是这样的,假设在G的列名RID是一样的,在实体的字段名称:

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

您能否分享一个适用于OP的用例的示例,以使您的答案更具描述性和完整性? – 2012-02-08 14:28:26

1

您可以使用PredicateBuilder根据您的需要动态构建linq查询。这将帮助您轻松构建linq表达式。至于会随着时间的推移而增长和增长的丑陋的开关,我会建议也许如果“名称”总是与你的linq表达式中的属性相关联(例如“age” - > .Age),那么你应该能够得到一些反射代码 - 让你检查,如果“名”不涉及同一名称的属性,如果是这样建立它的过滤器..

HTH

+0

非常好!我认为这正是我需要的。现在我只需要检查关于Dynamic LINQ的其他答案并决定哪一个更适合。我会选择胜出的答案。 – Tx3 2012-02-08 08:56:16

1

您可以使用,而不是仅仅LINQ ESQL:

Context.Entities 
    .Where("it.Age > @Age", new[] { new ObjectParameter("Age", age }); 

,你可以很容易地生成根据您的标准字符串表示你有过滤器。

以下是您需要的full reference to ESQL

1

可以使用反射代码,如:

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. 
     } 
+0

我认为这很好,很简单。 – Tx3 2012-02-08 09:01:01

+0

享受它!祝你好运。你也可以标记它... – TwTw 2012-02-08 09:02:59