Entity Framework Динамическое Где Предложение из Списка <object> - PullRequest
0 голосов
/ 02 мая 2018

После чистки интернета мне не удалось найти решение, которое я мог бы заставить работать. Я пытаюсь использовать динамический linq, чтобы позволить пользователю создать пользовательский запрос из формы Windows. Чтобы содержать каждое предложение where, я построил объект с именем WhereClause:

public class WhereClause
{
    public int id { get; set; }
    public string ColumnName { get; set; }
    public string Operator { get; set; }
    public string OperatorSymbol { get; set; }
    public object Value { get; set; }
    public string AndOr { get; set; }
    public string AndOrSymbol { get; set; }
}

Большинство говорит само за себя, но различие между символом оператора и символом оператора состоит в том, что оператор будет хранить «равно» или «больше, чем», где символ оператора будет «==» и «>» соответственно. AndOR работает аналогичным образом.

Затем, когда пользователь создает предложения where, создается новый объект WhereClause, который добавляется в List<WhereClause>

Когда приходит время выполнения запроса, я использую Entity Framework и Linq для построения запроса.

Я хотел бы сделать что-то вроде:

List<WhereClause> wheres; //populated via parameter in the encapsulating method.

DataContext db = new DataContext();
var query = from d in db.Database select d;

string whereClause = "";

foreach(WhereClause where in wheres){
    whereClause = whereClause + String.Format(" {0} {1} {2} {3}", where.ColumnName, where.OperatorSymbol, where.Value, where.AndOrSymbol);

    query.Where(whereClause);

}

Я пытался всеми способами построить предложения where, включая where(predicate, params) и форматирование предиката с использованием "@1", но не нашел правильного способа сделать это.

Вот как выглядит построитель запросов для контекста. enter image description here

Так что теперь я обращаюсь к вам, ребята за помощью ..

1 Ответ

0 голосов
/ 02 мая 2018

Вам нужно перевести ваш WhereClause объект в Expression, тогда вы можете использовать его как запрос. Вот пример:

Type yourType = typeof(YourGeneric);
ParameterExpression pe = Expression.Parameter(yourType , "x");
Expression left = Expression.Property(pe, yourType.GetProperty(whereClause.ColumnName));
Expression right = Expression.Constant(whereClause.Value, typeof(int));
Expression result = Expression.Equal(left, right);

Это пример для сравнения свойства int. Вам нужно несколько if (или switch), чтобы понять тип свойства и тип сравнения, который вам нужно сделать.

if (whereClause.Operator == "Greater Than") {
    result = Expression.GreaterThan(left, right);
}

Когда вы закончите, используйте Expression таким образом:

context.Set<YourGeneric>().Where(result);

Я рекомендую использовать дженерики (если возможно) для упрощения кода и работы. Вы также можете объединить больше выражений:

Expression result4 = Expression.AndAlso(result1, result2);
Expression finalRes = Expression.Or(result3, result4);
...