我有数据库列
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]"不能用于的参数方法"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);