LINQ to Entities - 方法无法识别
LINQ to Entities - Method not recognized
我在针对可查询数据集执行查询时遇到问题。
原始调用如下所示:
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;
}
下面的方法生成一个 Expression<Func<Book, bool>>
,它确定 Book
的给定 属性 是否小于给定(常数)值。您当前在 GetPropertyValue
中的 error-checking 代码可能可以通过捕获 ArgumentException
来替换,当您尝试为不存在的 属性.[= 创建表达式时将抛出该代码。 19=]
请注意,我假设您正在访问的 属性 是真正的数字,并且您对 Convert.ToInt32
的调用只是必要的,因为您的 GetPropertyValue
方法 return 是 object
.
Expression<Func<Book, bool>> GenerateLessThanExpression(string propertyName, int value)
{
var parameter = Expression.Parameter(typeof (Book));
var property = Expression.Property(parameter, propertyName);
var comparison = Expression.LessThan(property, Expression.Constant(value));
return Expression.Lambda<Func<Book, bool>>(comparison, parameter);
}
下面是 return 非常短的书籍的用法示例:
var filter = GenerateLessThanExpression("Pages", 5);
var filtered = books.Where(filter);
我在针对可查询数据集执行查询时遇到问题。 原始调用如下所示:
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;
}
下面的方法生成一个 Expression<Func<Book, bool>>
,它确定 Book
的给定 属性 是否小于给定(常数)值。您当前在 GetPropertyValue
中的 error-checking 代码可能可以通过捕获 ArgumentException
来替换,当您尝试为不存在的 属性.[= 创建表达式时将抛出该代码。 19=]
请注意,我假设您正在访问的 属性 是真正的数字,并且您对 Convert.ToInt32
的调用只是必要的,因为您的 GetPropertyValue
方法 return 是 object
.
Expression<Func<Book, bool>> GenerateLessThanExpression(string propertyName, int value)
{
var parameter = Expression.Parameter(typeof (Book));
var property = Expression.Property(parameter, propertyName);
var comparison = Expression.LessThan(property, Expression.Constant(value));
return Expression.Lambda<Func<Book, bool>>(comparison, parameter);
}
下面是 return 非常短的书籍的用法示例:
var filter = GenerateLessThanExpression("Pages", 5);
var filtered = books.Where(filter);