Выражение Linq для вызова Содержит метод с обнуляемым параметром - PullRequest
0 голосов
/ 27 марта 2020

У меня есть столбец базы данных

SelectListId int null

И у меня сложный фильтр на веб-странице, который я пытаюсь перенести на LinqToSql для получения отфильтрованных данных из базы данных.

У меня есть несколько выражений, которые работают, но с одним я борюсь.

Я хотел бы вызвать что-то вроде этого x => SelectedIdsByUser.Contains(x.SelectListId)

Итак, у меня есть функция, которая возвращает предикат

// this function works for 'SelectListId int not null' columns
public static Expression<Func<T, bool>> SelectListContainsPredicate<T>(string columnName, List<int> searchValues)
{
      var type = typeof(T);
      ParameterExpression parameter = Expression.Parameter(type, "x");
      ConstantExpression constant = Expression.Constant(true);

      // When column is invalid, return true
      PropertyInfo property = type.GetProperties().FirstOrDefault(p => p.Name == columnName);

      if (property == null || searchValues.Count == 0)
      {
          return Expression.Lambda<Func<T, bool>>(constant, parameter);
      }

      // Define expression :
      // x => SearchValues.Contains(x.Column)

      MemberExpression member = Expression.Property(parameter, property);

      MethodInfo method = typeof(List<int>).GetMethod("Contains");

      constant = Expression.Constant(searchValues);

      // Here it throws :
      // System.ArgumentException: Expression of type 'System.Nullable`1[System.Int32]' 
      // cannot be used for parameter of type 'System.Int32' of method 'Boolean Contains(Int32)'
      // Because: column is int? and List<int>.Contains(int?) doesn't work.
      Expression expression = Expression.Call(constant, method, member);

      return Expression.Lambda<Func<T, bool>>(expression, parameter);
}

но я получаю ошибку, потому что SelectListId - это Nullable<int>, но метод Contains имеет только параметр int. Что я могу сделать здесь, любая идея?

System.ArgumentException: выражение типа 'System.Nullable`1 [System.Int32]' нельзя использовать для параметра типа 'System.Int32' из метод 'Boolean Contains (Int32)'

Ответы [ 2 ]

0 голосов
/ 28 марта 2020

Я нашел решение здесь https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.expression.convert?view=netframework-4.8

есть метод Expression.Convert, я использовал: -)

Expression memberAsInt = Expression.Convert(member, typeof(Int32));

Expression expression = Expression.Call(constant, method, memberAsInt);

return Expression.Lambda<Func<T, bool>>(expression, parameter);
0 голосов
/ 28 марта 2020

используйте

x => ( x.SelectListId != null ) ? SelectedIdsByUser.Contains( (int)(x.SelectListId) ) : 0 

и замените 0 на целое значение.

...