LINQ 到实体 - 无法识别方法

本文关键字:识别 方法 实体 LINQ | 更新日期: 2023-09-27 18:31:34

我在对可查询数据集执行查询时遇到问题。原始调用如下所示:

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 到实体 - 无法识别方法

下面的方法生成一个Expression<Func<Book, bool>>,用于确定Book的给定属性是否小于给定(常量)值。您当前在 GetPropertyValue 中的错误检查代码可能会替换为捕获当您尝试为不存在的属性创建表达式时将引发的ArgumentException

请注意,我假设您正在访问的属性是真正的数字,并且您对Convert.ToInt32的调用只是因为您的GetPropertyValue方法返回一个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);
}

下面是仅返回非常短的书籍的示例用法:

var filter = GenerateLessThanExpression("Pages", 5);
var filtered = books.Where(filter);