C# 如何在lambda表达式中忽略转换为nullable?

C# 如何在lambda表达式中忽略转换为nullable?,c#,expression,expression-trees,linq-expressions,C#,Expression,Expression Trees,Linq Expressions,我试图为Odata构建一个表达式解析器,当字段为空时,我得到一个错误 public class UserRight { public bool? active } public void Test(){ Expression<Func<UserRight, bool>> expression = p => p.Active == true; } 但我想把它作为 {p => (p.Active == True)} 为了避免这种“转换”。 有

我试图为Odata构建一个表达式解析器,当字段为空时,我得到一个错误

public class UserRight
{
    public bool? active
}

public void Test(){
    Expression<Func<UserRight, bool>> expression = p => p.Active == true;
}
但我想把它作为

{p => (p.Active == True)}
为了避免这种“转换”。 有没有一个简单的方法?
因为我的解析器已经准备好了,我不想仅仅因为一个可为null的字段而重建它。

当您使用可为null的变量时,您应该检查它是否有值,如果是真的,那么就访问该值。大概是这样的:

p=> p.Active.HasValue ? p.Active.Value : false; //'== true' unnecessary


我不确定您的解析器是如何工作的,但我认为这可以工作。

不,没有办法避免它。您调用的运算符接受的是
bool?
,而不是
bool
,因此参数必须是
bool?
,否则无法编译。从convert表达式可以看出,存在从
bool
bool?
的隐式转换。如果没有隐式转换,它将不是有效的表达式


理论上,您可以手动构造自己的表达式,使用一个真正的可为空的布尔常量值,但无法使lambda“自动”生成这样的表达式,尝试创建新表达式几乎肯定比让查询提供程序处理转换表达式要复杂得多。

老实说,我不喜欢布尔属性中的null, 更适合您的情况:

Expression<Func<UserRight, bool>> expression = p => p.Active ?? false
Expression=p=>p.Active??假的

这将考虑空值为假,并将解决您的情况。

<代码> P= > PcActive=Trime实际上是<代码> P= > P Active==(BOOL)Trime< /Cord>。内置表达式树由
Convert
expression表示。所以你无法避免。你说你有错误,错误是什么?可能有更好的方法来解决你的问题。我在我的电脑上做了一些测试,表达式生成我
{p=>(p.active==Convert(True))
,“?false”生成我
{p=>(p.active?false)}
,.Value”生成
{p=>(p.active.Value==True)}
他使用的是“active”,即bool?,但必须使用“现行价值观“如果你想要一个女人。我认为我下面的答案是有效的。@DrkDeveloper您只是在更改您希望他们的解析器能够支持的内容,将转换表达式转换为条件表达式,并为不同的属性设置两个不同的属性获取程序,现在,他们还要求任何使用此查询提供程序的人都不要编写一个完全合理的查询,而应该期望查询提供程序能够处理,并且每次都必须编写更复杂的内容。但是如果他使用
p=>p.GetValueOrDefault()==true
,我认为解析器必须理解它。这里的问题不是“真的”,而是p.Active,IMHO。@DrkDeveloper为什么他们的查询提供者必须理解它?如果你想支持这两个,我想我可以看到。这并没有消除OP的问题,只是建议他们也应该支持一个新的表达式。OP希望避免将“true”作为Convert(true,Nullable'1)。发生这种情况是因为p.Active可为空。但是p.Active.Value不是,p.GetValueOrDefault()不是。如果查询提供程序理解p.Active,那么它应该理解p.Active.Value。即使是@Jonathan Santiago的回答也很好。这确实有效,但我仍然会有一些问题。我用它把表达式转换成OData表达式。因此,现在不是生成“active eq true”,而是生成“active.GetValueOrDefault eq true”。我正在尝试找到另一种方法,感谢您的快速回答@费尔南多看乔纳森回答。
p=> p.Active.GetValueOrDefault(); //the same but shorter.
Expression<Func<UserRight, bool>> expression = p => p.Active ?? false