正在创建等于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;
        }

正在创建等于int32的IQueryable

不清楚您为什么要创建这个扩展,因为您可以简单地编写以下内容:

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,查询提供程序就会为您完成所有这些操作。