正在创建等于int32的IQueryable
本文关键字:int32 IQueryable 创建 | 更新日期: 2023-09-27 18:26:00
我正在尝试创建一个查询扩展,它将比较一个可为null的int sql列值和一个值。但我已经挣扎了8个多小时才找到有效的解决方案。
我已经在这方面找到了很多帮助。但所有的言论对我没有帮助
我已经修改了很多次代码,但似乎都不起作用。我想创建类似于WHERE ManagerID IN(10,20,30)的东西
主代码
IQueryable<Users> query = _context.CreateObjectSet<Users>();
query = query.IsMember(a => a.ManagerID, new Int32?[] { 10,20,30 });
return query.ToList();
当前正在执行查询。ToList();它还给我一个
无法创建类型为"System.Object"的常数值。此上下文中只支持基元类型或枚举类型。
public static IQueryable<T> IsMember<T>(this IQueryable<T> source, Expression<Func<T, Int32?>> stringProperty, params Int32?[] searchTerms)
{
if (searchTerms == null || !searchTerms.Any())
{
return source;
}
Expression orExpression = null;
foreach (var searchTerm in searchTerms)
{
var searchTermExpression = Expression.Constant(searchTerm, typeof(object)); // <<--- This cast would make it no longer a primitive type
var containsExpression = Expression.Call(stringProperty.Body, typeof(Int32?).GetMethod("Equals"), searchTermExpression);
orExpression = BuildOrExpression(orExpression, containsExpression);
}
var completeExpression = Expression.Lambda<Func<T, bool>>(orExpression, stringProperty.Parameters);
return source.Where(completeExpression);
}
private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)
{
return existingExpression == null ? expressionToAdd : Expression.OrElse(existingExpression, expressionToAdd);
}
标记为给常量提供另一个数据类型的行确实导致了问题,但如果我不将其设为object类型,Expression将无法工作,因为它无法匹配Int32?数据类型。
有人能帮我吗?
感谢
=========================================
其他信息
这确实是为了有一个更大的画面。我只是想创建一些更动态的东西,也可以用于其他项目。
我想使用一些看起来比所有那些多线更有吸引力的功能
query = query.Like(a => a.UserName, filter.UserName, true);
query = query.Equals(a => a.UserTown, filter.UserTown, true);
query = query.IsMember(a => a.Division, filter.Division); // is an array of possible divisions
它适用于基于字符串的Like和Equals。但是想要有一个类似的产品(可为空)整数
我受到以下帖子的启发。它创建了一个搜索功能(我为我的项目将其重命名为Like)链路
我想创造其他类似的东西。最后一个布尔值是验证列中是否允许为null。
使用扩展的原因是,我的过滤器页面中也有很多过滤器。有了这个扩展,我可以很容易地在Like and Equal函数的开头检查是否给定了一个过滤器,而不检查我的过滤器是否有值20x。
public static IQueryable<T> Like<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, string searchTerm, bool isnullValueAllowed)
if (String.IsNullOrEmpty(searchTerm))
{
return query;
}
不清楚您为什么要创建这个扩展,因为您可以简单地编写以下内容:
query.Where(user => (new[]{10,20,30}).Contains(user.ManagerId)).ToList();
然而,假设实际用例比您给出的示例稍微复杂一些,您是否可以根据searchTerm.HasValue()
是否为true,将表达式构造为与常量Int32的比较或与null的比较?
此处需要使用相等运算符==
,而不是Equals
方法。它实际上让你的表达式代码简单了一点:
foreach (var searchTerm in searchTerms)
{
var comparison = Expression.Equals(stringProperty.Body,
Expression.Constant(searchTerm));
orExpression = BuildOrExpression(orExpression, comparison);
}
当然,正如其他人所提到的,您不需要构建一个表示每个比较的OR的表达式,只需在lambda中的集合上使用Conatains
,查询提供程序就会为您完成所有这些操作。