我正在尝试通过LINQ / SQL Server解析表达式,但它似乎无法处理表达式并且只是完全跳过它(虽然它适用于内存数据集)。
public static Func<TSource, bool> WhereNotNullClause<TSource>(string propertyName)
{
var type = typeof(TSource);
var expression = Expression.Parameter(type, "p");
var propertyNameReference = Expression.Property(expression, propertyName);
var propertyValueReference = Expression.Constant(null);
return Expression.Lambda<Func<TSource, bool>>(
Expression.NotEqual(propertyNameReference, propertyValueReference),
new[] { expression }).Compile();
}
如下所示:
var whereNotNullSelector = Expressions.WhereNotNullClause<ContactItem>("property");
var contactItems = context.ContactItems.Where(whereNotNullSelector).ToList();
生成的SQL不包含where子句,因此在查询结算后似乎执行了where。 在我能够解决这个问题之前,还需要注意什么?
答案 0 :(得分:3)
您的方法返回Func
而不是Expression
。代码必须使用Enumerable.Where
而不是Queryable.Where
。这意味着它需要实现数据,从数据库中拖动整个数据集并在本地运行过滤器。只需将返回类型更改为表达式,然后删除.Compile
:
public static Expression<Func<TSource, bool>> WhereNotNullClause<TSource>(string propertyName)
{
var type = typeof(TSource);
var expression = Expression.Parameter(type, "p");
var propertyNameReference = Expression.Property(expression, propertyName);
var propertyValueReference = Expression.Constant(null);
return Expression.Lambda<Func<TSource, bool>>(
Expression.NotEqual(propertyNameReference, propertyValueReference),
new[] { expression });
}
关于Expression
而不是Func
的原因的一些额外阅读here。将表达式视为数据而不是实际的委托,这意味着Linq to SQL可以将表达式树转换为SQL,而Func本质上是一个黑盒子。