Linq表达实体子的条件

时间:2016-12-11 13:51:08

标签: c# entity-framework linq linq-expressions

您好,

如何通过linq表达式构建以下语句以便转换为sql?

builder.Where(e => e.SomeChild.Name.ToLower() == "something");

builder是DbContext。当我直接调用它时,它就像这样正确地解释了

select ... from someTable 
inner join childTable on ... 
where LOWER(childTable.Name) = @someParam

所以我用这种方式构建where条件:

private readonly Expression<Func<TEntity, TProperty>> _property;

private Expression<Func<TEntity, bool>> insensitiveEqualityPredicate(string formula)
        {
            var parameter = Expression.Parameter(typeof(TEntity));
            var property = (PropertyInfo)((MemberExpression)_property.Body).Member;
            var propertyParameter = Expression.Parameter(property.DeclaringType);
            var lowerExpression = Expression.Call(
                    Expression.Invoke(_property, propertyParameter),
                    typeof(string).GetMethods().Where(m => m.Name == "ToLower" && m.GetParameters().ToList().Count == 0).FirstOrDefault()
                    );
            return Expression.Lambda<Func<TEntity, bool>>(
                Expression.Equal(
                    lowerExpression,
                    Expression.Constant(formula.ToLower(), typeof(string))
                ),
                parameter
            );
        }

它像魅力一样:

_property = e => e.Name;
...
builder.Where(insensitiveEqualityPredicate("whatever"));

但不适合儿童的条件:

_property = e => e.SomeChild.Name;
...
builder.Where(insensitiveEqualityPredicate("whatever"));

由于:

The LINQ expression 'Param_0.Name.Equal("whatever")' could not be translated and will be evaluated locally.

什么是正确的方法?

提前谢谢。

1 个答案:

答案 0 :(得分:3)

根据我的理解,您有_property类型的字段Expression<Func<TEntity, TProperty>>(在此特定情况下,它实际上是Expression<Func<TEntity, string>>),它使用lambda表达式初始化,如{{1 },e => e.Name等。

为了构建所需的谓词,您可以重用e => e.SomeChild.Name表达式参数,并使用Body属性作为新表达式的基础:

_property