返回空的linq表达式

时间:2013-09-03 13:14:26

标签: c# linq

我在基类中有一个WhereFilter属性,如下所示:

public virtual Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
    get { return null; }
}

当它被覆盖时,我想返回别的东西而不是null,所以我可以使用谓词构建器扩展和(来自LinqKit)所以我可以按如下方式编写代码:

public override Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
    get { return base.WhereFilter.And(x => x.CustomerID == 1); }
}

但是这会产生错误,因为WhereFilter为null(对象引用未设置为对象的实例)。

目前我写的是:

public override Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
    get { return x => x.CustomerID == 1; }
}

因此,当有另一个子类覆盖它时,基类属性将丢失。

有什么方法可以解决这个问题?在sql我做的是使用一个虚拟,其中1 = 1 thingy,这可以在linq中类似地完成吗?

4 个答案:

答案 0 :(得分:17)

LINQ相当于SQL的1=1“thingy”是一个总是返回true的谓词:

x => true

更改默认方法,如下所示:

public virtual Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
    get { return x=>true; }
}

答案 1 :(得分:5)

您只需检查继承的属性是否返回null

public override Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
    get {
        var baseResult = base.WhereFilter;
        if (baseResult == null) {
            return x => x.CustomerID == 1;
        } else {
            return base.WhereFilter.And(x => x.CustomerID == 1);
        }
    }
}

IMO这将比看似毫无意义的虚拟值更具可读性,这些虚拟值将使您(或其他任何使用该代码的人)在以后想知道那是什么。 (它甚至可能在运行时产生更少的开销。)

如果您坚持使用较少的行,则可以使用if运算符缩短else - ?:表达式。


编辑:进一步思考这个问题,你可以看到它是一个缺点,每个覆盖该属性的人都必须编写如此多的代码,这可能会引入错误。但是,在调用继承的代码时,依赖于不包含任何此类错误的覆盖方法是一个值得怀疑的设计选择,就像您提出的模型一样,覆盖器也可能只返回其新谓词而不调用And

更清洁的设计IMO将创建虚拟属性protected,并使其仅返回新谓词(或null)。然后,公共可访问(和非虚拟)属性将负责检索当前和任何超类的任何谓词,并在有多个时将它们与And组合。

答案 2 :(得分:2)

您可以执行以下操作:

    public virtual Expression<Func<CustomerCustomerType, bool>> WhereFilter    
    {
        get { return customerCustomerType => true; }
    }

这是一个总是返回true的表达式。

答案 3 :(得分:0)

如果你在调试中,你不能使用lambda表达式(EF),你可以用它来欺骗linq,如果你使用标准的linq,在末尾使用带有.Compile()的句子:

表达式&GT;的λ(Expression.Constant(真),Expression.Parameter(typeof运算(T)))