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