.net linq到实体的不区分大小写的动态搜索
对于这个问题,答案表明我们不能使用LINQtoSQL或LINQtoEntities 如果我写.net linq到实体的不区分大小写的动态搜索,.net,linq,.net,Linq,对于这个问题,答案表明我们不能使用LINQtoSQL或LINQtoEntities 如果我写 Expression toLower = Expression.Call(memberAccess, typeof(T).GetMethod("IndexOf", new[] { typeof(T), typeof(StringComparison) })); Expression condition = Expressio
Expression toLower = Expression.Call(memberAccess, typeof(T).GetMethod("IndexOf",
new[] { typeof(T), typeof(StringComparison) }));
Expression condition = Expression.Call(toLower,
typeof(string).GetMethod("Contains"),
Expression.Constant(value.ToString().ToLower()));
lambda = Expression.Lambda(condition, parameter);
Expression toLower = Expression.Call(memberAccess, typeof(string).GetMethod("IndexOf",
new[] { typeof(string), typeof(StringComparison) }));
我得到一个错误:
Value cannot be null. Parameter name: method
如果我写
Expression toLower = Expression.Call(memberAccess, typeof(T).GetMethod("IndexOf",
new[] { typeof(T), typeof(StringComparison) }));
Expression condition = Expression.Call(toLower,
typeof(string).GetMethod("Contains"),
Expression.Constant(value.ToString().ToLower()));
lambda = Expression.Lambda(condition, parameter);
Expression toLower = Expression.Call(memberAccess, typeof(string).GetMethod("IndexOf",
new[] { typeof(string), typeof(StringComparison) }));
我得到的错误是:
Incorrect number of arguments supplied for call to method 'Int32 IndexOf(System.String, System.StringComparison)'
提前谢谢
编辑:
以下是代码片段,我需要能够在Installive筛选器中执行一个案例:
public static IQueryable<T> Where<T>(this IQueryable<T> query,
string column, object value, WhereOperation operation)
{
if (string.IsNullOrEmpty(column))
return query;
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in column.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
//change param value type
//necessary to getting bool from string
ConstantExpression filter = Expression.Constant
(
Convert.ChangeType(value, memberAccess.Type)
);
//switch operation
Expression condition = null;
LambdaExpression lambda = null;
switch (operation)
{
//equal ==
case WhereOperation.Equal:
condition = Expression.Equal(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//not equal !=
case WhereOperation.NotEqual:
condition = Expression.NotEqual(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//string.Contains()
case WhereOperation.Contains:
condition = Expression.Call(memberAccess,
typeof(string).GetMethod("Contains"),
Expression.Constant(value));
lambda = Expression.Lambda(condition, parameter);
break;
}
MethodCallExpression result = Expression.Call(
typeof(Queryable), "Where",
new[] { query.ElementType },
query.Expression,
lambda);
return query.Provider.CreateQuery<T>(result);
}
公共静态IQueryable Where(此IQueryable查询,
字符串列,对象值,WhereOperation(操作)
{
if(string.IsNullOrEmpty(column))
返回查询;
ParameterExpression参数=Expression.parameter(query.ElementType,“p”);
MemberExpression memberAccess=null;
foreach(column.Split('.')中的var属性)
memberAccess=MemberExpression.Property
(memberAccess??(参数作为表达式),属性);
//更改参数值类型
//从字符串中获取布尔值所必需的
ConstantPression过滤器=表达式常数
(
Convert.ChangeType(值,memberAccess.Type)
);
//开关操作
表达式条件=null;
LambdaExpression lambda=null;
开关(操作)
{
//相等的==
操作情况。等于:
条件=表达式.Equal(memberAccess,筛选器);
lambda=表达式.lambda(条件、参数);
打破
//不平等=
案例WhereOperation.NotEqual:
条件=Expression.NotEqual(memberAccess,filter);
lambda=表达式.lambda(条件、参数);
打破
//string.Contains()
案例操作。包含:
条件=表达式.Call(memberAccess,
typeof(string).GetMethod(“包含”),
表达式。常量(值));
lambda=表达式.lambda(条件、参数);
打破
}
MethodCallExpression结果=表达式.Call(
typeof(可查询),“Where”,
新[]{query.ElementType},
query.Expression,
lambda);
返回query.Provider.CreateQuery(结果);
}
您试图调用IndexOf
,而不指定任何参数。然后尝试将结果用作Contains
调用的目标,这有点奇怪。。。我怀疑你真的想要:
Expression indexOf = Expression.Call(memberAccess, "IndexOf", null,
Expression.Constant(value.ToString()),
Expression.Constant(StringComparison.OrdinalIgnoreCase));
Expression condition = Expression.NotEqual(indexOf, Expression.Constant(-1));
lambda = Expression.Lambda(condition, parameter);
如果你能给我们更多关于你想要达到的目标的信息——最好是通过一个简短但完整的计划——帮助你会更容易
编辑:以编译时安全的方式使用Where
更有意义,如下所示:
Expression<Func<T, bool>> lambda = null;
...
lambda = Expression.Lambda<Func<T, bool>>(condition, parameter);
return query.Where(lambda);
表达式lambda=null;
...
lambda=表达式.lambda(条件、参数);
返回查询.Where(lambda);
将代码修改为:
Expression toLower = Expression.Call(memberAccess, "ToLower", null, null);
lambda = Expression.Lambda(condition, parameter);
我添加了代码,您给出的建议,给出了编译时错误。@Priya10:我现在编辑了答案-我错过了一个参数。但这样通过反射调用
Where
是很奇怪的。也将为此进行编辑…我得到一个错误:LINQ to Entities无法识别方法“Int32 IndexOf(System.String,System.StringComparison)”方法,并且该方法无法转换为存储表达式。@Priya10:好的,因此Entity Framework不支持该方法。在尝试自己将其转换为手动生成的表达式树之前,通常值得使用硬编码LINQ查询(由编译器转换为表达式树)来测试这类内容。我以为你已经这么做了。。。所以我不知道你的总体目标是什么,但你现在已经设法得到了我认为你想要的表达式树-它只是不受支持:(哦,你的意思是说,这是不可能的。你有没有参考资料,可以用于使用linq的通用查询构建,并提供不区分大小写的过滤器