Генерация оператора LinqToEntities Where в зависимости от выбора пользователя - PullRequest
1 голос
/ 08 февраля 2012

У меня есть пользовательский интерфейс, в котором пользователь может выбрать столбец сетки (например, возраст) и оператор (меньше, равно или больше) для этого столбца.

Затем данные сетки фильтруются в соответствии с выбором.

У меня есть следующие классы, которые десериализованы из 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.Теперь мне просто нужно сравнить разные решения.

Ответы [ 5 ]

1 голос
/ 08 февраля 2012

Вы можете использовать код отражения, например:

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.
        }
1 голос
/ 08 февраля 2012

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

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

Вы можете легко сгенерировать строковое представление для ваших критериев на основе имеющегося фильтра.

Здесь fullссылка на ESQL , если вам это нужно.

1 голос
/ 08 февраля 2012

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

Edit:

Пример запроса Dynamic 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);
1 голос
/ 08 февраля 2012

Вы можете передать методу Where объект System.Linq.Expressions.Expression, который вы создаете из своих входных данных.Вот пример того, как составить выражения предикатов для использования с EF или Linq2Sql: Динамически составлять предикаты выражений

1 голос
/ 08 февраля 2012

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

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...