2012-02-08 4 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. 
} 

Любые идеи, как создать более общее решение для этой проблемы?

Обновление Похоже, что существует множество способов решения более чистого решения, чем один миллиард, если заявления. Теперь мне просто нужно сравнить различные решения.

ответ

1

вы можете использовать Dynamic LINQ для создания запроса динамически

Edit:

пример для динамического 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); 
+0

Не могли бы вы поделиться образцом, который будет применим к случаю использования ОП, чтобы сделать ваш ответ более наглядным и полным? –

1

Вы можете использовать PredicateBuilder для динамического создания запросов linq на основе того, что вы хотите. Это поможет вам легко создать выражение linq. Что касается уродливого коммутатора, который со временем будет расти и расти, я бы предположил, что если «имя» всегда связано с свойством в выражении linq (например, «age» -> .Age), то вы должны иметь возможность получить это с некоторым кодом отражения - так проверить, если «имя» не относятся к собственности одного и того же имени, и если это так построить фильтр для него ..

HTH

+0

Очень хорошо! Я думаю, что это именно то, что мне нужно. Теперь мне просто нужно проверить другой ответ на Dynamic LINQ и решить, какой из них более подходит. Тогда я выберу выигрышный ответ. – Tx3

1

Вы можете перейти к Где метод а System.Linq.Expressions.Expression объект, который вы составляете от вашего входа. Вот пример того, как составить предикатные выражения для использования с EF или Linq2Sql: Dynamically Composing Expression Predicates

1

Вы можете использовать ESQL, а не только LINQ:

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

+0

Наслаждайтесь! удачи. вы также можете пометить его ... – TwTw