我正在尝试创建一个查询扩展,它将可空的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;
}
答案 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
会为你做所有这些。