要调用具有可为null参数的Contains方法的Linq表达式



我有数据库列

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">

使用

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

并将0替换为intendant值。

我在这里找到了解决方案https://learn.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);

最新更新