簡體   English   中英

使用可為空參數調用包含方法的 Linq 表達式

[英]Linq expression to call Contains method with nullable parameter

我有數據庫列

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);
}

但我收到一個錯誤,因為SelectListIdNullable<int>Contains方法只有int參數。 我能在這里做什么,有什么想法嗎?

System.ArgumentException:“System.Nullable`1[System.Int32]”類型的表達式不能用於“Boolean Contains(Int32)”方法的“System.Int32”類型的參數

我在這里找到了解決方案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);

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

並用預期值替換 0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM