Лямбда-выражение с содержанием не работает - PullRequest
0 голосов
/ 18 мая 2018

Я новичок в Lambda Expressions и у меня возникли проблемы с получением нужного мне результата.Точнее говоря, у меня возникают проблемы с получением правильной части лямбда-выражения, содержащей LINQ.

Вот что у меня есть:

// The following line is what I want for my Final Result
var distinctValues = db.Equipment.Where(m => m.Model != null && m.Model.Contains(SearchTerm)).Select(m => m.Model).Distinct().ToList();

var queryableData = db.Equipment.AsQueryable();

var parameterExpression = Expression.Parameter(typeof(Equipment), Column);
var constant = Expression.Constant(null);

var property = Expression.Property(parameterExpression, Column);
var expression1 = Expression.NotEqual(property, constant);
var expression2 = Expression.Equal(property,constant);

Expression callContains = Expression.Call(typeof(Queryable), "Contains", new[] { <string> } );

var lambda1 = Expression.Lambda<Func<Equipment, bool>>(expression1, parameterExpression);
var lambda2 = Expression.Lambda<Func<Equipment, string>>(property, parameterExpression);
var lambda3 = Expression.Lambda<Func<Equipment, bool>>(callContains, parameterExpression);
var compiledLambda1 = lambda1.Compile();
var compiledLambda2 = lambda2.Compile();

Я передаю любое свойство ипоисковый запрос, и я хочу сгенерировать эквивалент запроса LINQ, приведенного выше, в качестве лямбда-выражения, которое начинается с «var diverValues».У меня возникли проблемы со строкой, которая начинается с "Выражение callContains".

Любая помощь очень ценится.

Спасибо,

Пит

Ответы [ 2 ]

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

Спасибо, Ксанатос.С вашей помощью я смог решить мою проблему.Вот окончательное решение, которое я придумал.Всего несколько незначительных изменений:

  // m => 
                var parameterExpression = Expression.Parameter(typeof(Equipment), "m");

                // m.Model
                var modelProperty = Expression.Property(parameterExpression, Column);
                // m.Model != null
                var nonNullExpression = Expression.NotEqual(modelProperty, Expression.Constant(null, typeof(string)));

                // SearchTerm
                var searchTermConstant = Expression.Constant(SearchTerm);

                // m.Model.Contains(SearchTerm)
                var containsExpression = Expression.Call(modelProperty, "contains", null, searchTermConstant);

                // m.Model != null && m.Model.Contains(SearchTerm)
                var andExpression = Expression.AndAlso(nonNullExpression, containsExpression);

                var lambda1 = Expression.Lambda<Func<Equipment, string>>(modelProperty, parameterExpression);
                var lambda2 = Expression.Lambda<Func<Equipment, bool>>(andExpression, parameterExpression);

                var compiledLambda1 = lambda1.Compile();
                var compiledLambda2 = lambda2.Compile();

                var distinctValues1 = db.Equipment.Where(compiledLambda2).Select(compiledLambda1).Distinct().ToList();

Сначала я использовал другую перегрузку для containsExpression.Во-вторых, я хотел свойство модели в качестве параметра.По сути, я хотел передать свойство переменной (столбец) и переменную searchterm.Вот и все.

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

Contains - это string.Contains.Итак, учитывая:

static readonly MethodInfo contains = (from x in typeof(string).GetMethods(BindingFlags.Instance | BindingFlags.Public)
                                       where x.Name == nameof(string.Contains) && !x.IsGenericMethod
                                       let pars = x.GetParameters()
                                       where pars.Length == 1 &&
                                           pars[0].ParameterType == typeof(string)
                                       select x).Single();

, тогда дерево выражений .Where() будет:

// m => 
var parameterExpression = Expression.Parameter(typeof(Equipment), "m");

// m.Model
var modelProperty = Expression.Property(parameterExpression, nameof(Equipment.Model));
// m.Model != null
var nonNullExpression = Expression.NotEqual(modelProperty, Expression.Constant(null, typeof(string)));

// SearchTerm
var searchTermConstant = Expression.Constant(SearchTerm);

// m.Model.Contains(SearchTerm)
var containsExpression = Expression.Call(modelProperty, contains, searchTermConstant);

// m.Model != null && m.Model.Contains(SearchTerm)
var andExpression = Expression.AndAlso(nonNullExpression, containsExpression);

// m => ...
var lambda = Expression.Lambda<Func<Equipment, bool>>(andExpression, parameterExpression);
...