对于question,答案表明我们不能将LINQ to SQL或linq用于实体。
如果我写
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);
我收到错误:
Value cannot be null. Parameter name: method
如果我写
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)'
提前致谢
修改 这是片段,我需要能够做一个不区分大小写的过滤器:
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);
}
答案 0 :(得分:3)
将代码修改为:
Expression toLower = Expression.Call(memberAccess, "ToLower", null, null);
lambda = Expression.Lambda(condition, parameter);
答案 1 :(得分:2)
您试图在不指定任何参数的情况下调用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);