C# LINQ到实体-无法识别方法

C# LINQ到实体-无法识别方法,c#,linq-to-entities,expression-trees,C#,Linq To Entities,Expression Trees,我在对可查询数据集执行查询时遇到了一个问题。 最初的调用如下所示: books = books.Where(b => (GetPropertyValue(b, filter.CategoryProperties.DbName) == null ? 0 : Convert.ToInt32(GetPropertyValue(b, filter.CategoryProperties.DbName))) < Convert.ToInt32(filter.Value)); 如果您能帮助生成正

我在对可查询数据集执行查询时遇到了一个问题。 最初的调用如下所示:

books = books.Where(b => (GetPropertyValue(b, filter.CategoryProperties.DbName) == null ? 0 : Convert.ToInt32(GetPropertyValue(b, filter.CategoryProperties.DbName))) < Convert.ToInt32(filter.Value));
如果您能帮助生成正确的表达式树,我们将不胜感激:-)

编辑: 下面是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;
    }

下面的方法生成一个
表达式
,该表达式确定
书籍
的给定属性是否小于给定(常量)值。您当前在
GetPropertyValue
中的错误检查代码可能会被捕获
ArgumentException
替换,该异常将在您尝试为不存在的属性创建表达式时抛出

请注意,我假设您正在访问的属性是真正的数字属性,并且您对
Convert.ToInt32
的调用是必要的,因为
GetPropertyValue
方法返回一个
对象

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);
}

您自己回答了问题:不能在Linq to entities查询中使用C#方法,因为该方法的调用不能转换为SQL。如果您让编译器构建表达式,或者您自己构建表达式,它不会改变任何东西-它仍然无法转换为SQL。我认为解决方案
自己构建表达式树
的意思是:将方法
GetPropertyValue
的内容转换为表达式,因此可以将其转换为SQL。目前,您将方法调用转换为表达式树,但您必须将整个方法转换为表达式树。能否将方法
GetPropertyValue
添加到问题中?@Maarten用代码编辑:-)您的方法
GetPropertyValue
使用反射来查找属性值。这很难翻译成SQL。我将在此添加一条注释。在Expression.LessThan中,我必须解析一个类型作为第三个参数,否则我无法让它工作:-)您能澄清一下吗?上面的代码使用示例类进行了测试,并按原样工作。您“解析”的是什么类型?我解析了property.type,当然,我要确保与之比较的值是同一类型的
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>> 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);