我正面临对Queryable数据集执行查询的问题。 原始呼叫看起来是这样的:LINQ to Entities - 未识别方法
books = books.Where(b => (GetPropertyValue(b, filter.CategoryProperties.DbName) == null ? 0 : Convert.ToInt32(GetPropertyValue(b, filter.CategoryProperties.DbName))) < Convert.ToInt32(filter.Value));
这让我的方法不承认错误。 这当然是由于对GetPropertyValue的调用所致。然后我读到我应该自己构建表达树。 导致下面的代码:
public IQueryable<Books> GetExpression(IQueryable<Books> books, BookCategoryMapping filter)
{
var booksExpression = Expression.Parameter(typeof(Books), "b");
var methodInfo = this.GetType().GetMethod("GetPropertyValue");
var value = Expression.Call(methodInfo, booksExpression, Expression.Constant(filter.CategoryProperties.DbName));
var left = Expression.Constant(value);
var right = Expression.Constant(filter.Value);
var expression = Expression.Equal(left, right);
var whereExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { books.ElementType }, books.Expression, Expression.Lambda<Func<Books, bool>>(expression, new ParameterExpression[] { booksExpression }));
return books.Provider.CreateQuery<Books>(whereExpression);
}
唯一的问题是,我得到了同样的错误。看起来下面一行只产生一个表达式而不是所述表达式的值。
var value = Expression.Call(methodInfo, booksExpression, Expression.Constant(filter.CategoryProperties.DbName));
任何产生正确的表达式树的帮助,将不胜感激:-)
编辑: 这里的GetPropertyValue方法:
public static object GetPropertyValue(object obj, string name)
{
try
{
return obj.GetType().GetProperty(name)?.GetValue(obj, null);
}
catch (Exception ex)
{
LogManager.Log(LogLevel.Error, null, ex);
}
return obj;
}
你回答了你自己的问题:你不能在LINQ到实体查询中使用C#方法,因为的调用方法不能转换为SQL。如果让编译器构建表达式,或者如果自己构建表达式,它不会改变任何内容 - 它仍然不能转换为SQL。 – Maarten
我认为解决方案'自己构建表达式树“的意思就是:将方法'GetPropertyValue'的内容转换为表达式,以便**可以转换为SQL。目前,您将方法**的调用**转换为表达式树,但必须将整个方法**转换为表达式树。 – Maarten
您可以将“GetPropertyValue”方法添加到问题中吗? – Maarten