我在基类中有一个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中类似地完成吗?
答案 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)))