SQL Server

时间:2017-07-13 10:09:21

标签: c# sql-server linq lambda entity-framework-5

我正在尝试通过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。 在我能够解决这个问题之前,还需要注意什么?

1 个答案:

答案 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本质上是一个黑盒子。