创建IQueryable到Equal int32?

时间:2014-10-08 13:35:54

标签: c# entity-framework iqueryable

我正在尝试创建一个查询扩展,它将可空的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();

目前执行query.ToList()时;它给我一个

无法创建类型&#39; System.Object&#39;的常量值。在此上下文中仅支持原始类型或枚举类型。

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

标记为赋予常量另一种数据类型的行确实导致了问题,但是如果我不使其成为对象类型,则表达式将无效,因为它无法与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) link

我想创造其他类似的东西。最后一个布尔值是验证列中是否可以为空。

使用扩展程序的原因是我的过滤器页面中还有很多过滤器。 有了这个扩展,我可以轻松检查我的Like和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;
        }

2 个答案:

答案 0 :(得分:0)

目前尚不清楚为什么要创建此扩展名,因为您可以简单地编写如下内容:

query.Where(user => (new[]{10,20,30}).Contains(user.ManagerId)).ToList();

但是,假设实际用例比您给出的示例稍微复杂一些,您是否可以将表达式构造为与常量Int32的比较或与null的比较,具体取决于searchTerm.HasValue()是真的吗?

答案 1 :(得分:0)

您需要在此使用等于运算符==而不是Equals方法。它实际上使你的表达式代码更简单:

foreach (var searchTerm in searchTerms)
{
    var comparison = Expression.Equals(stringProperty.Body, 
        Expression.Constant(searchTerm));

    orExpression = BuildOrExpression(orExpression, comparison);
}

当然,正如其他人所提到的,您不需要构建表示每个比较的OR的表达式,您只需在lambda中的集合和查询提供程序上使用Conatains会为你做所有这些。