Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ查询可为空的值_C#_.net_Linq - Fatal编程技术网

C# 使用LINQ查询可为空的值

C# 使用LINQ查询可为空的值,c#,.net,linq,C#,.net,Linq,我试图弄清楚如何在LINQ中进行一些值可以为null的查询 下一张是我的桌子: ID int Key1 int Key2 int? Key3 int? Value string uniq = Key1+Key2+Key3+Value 现在我需要检查现有记录是否已经基于唯一约束存在 我尝试了以下方法: Object tmp = model.table.FirstOrDefault(row => row.Key1 == newItem.Key1 &&

我试图弄清楚如何在LINQ中进行一些值可以为null的查询

下一张是我的桌子:

ID int
Key1 int
Key2 int?
Key3 int?
Value string

uniq = Key1+Key2+Key3+Value
现在我需要检查现有记录是否已经基于唯一约束存在

我尝试了以下方法:

Object tmp = model.table.FirstOrDefault(row => row.Key1 == newItem.Key1 &&
             (row.Key2.HasValue && newItem.Key2.HasValue && row.Key2.Value == newItem.Key2.Value) &&
             (row.Key3.HasValue && newItem.Key3.HasValue && row.Key3.Value == newItem.Key3.Value) &&
             row.Value == newItem.Value);
以及:

但是当其中一个键为空时,这两个键都没有得到正确的结果


有没有一种方法可以编写正确的LINQ查询?

不久前,我编写了一个小函数来处理此类情况:

专用函数EqualObThNullByVal int1作为Int32?,ByVal int2作为Int32?作为布尔值 选择Case True 案例int1为零,案例int2为零 返回真值 案例int1为零,同样int2为零或同样int1为零,同样int2为零 返回错误 案例int1不是零,案例int2也不是零 返回int1=int2 结束选择 端函数 它在VB.NET中,但在C中转换它应该很简单:

私有布尔EqualObThNullable int1,Nullable int2{ 切换为真{ 案例int1==null&&int2==null: 返回true; 案例int1==null&&int2!=null | | int1!=null&&int2==null: 返回false; 案例int1!=null&&int2!=null: 返回int1==int2; } } 然后,你可以简单地写:

Object tmp = model.table.FirstOrDefault(row =>
                      EqualOrBothNull(row.Key1, newItem.Key1) &&
                      EqualOrBothNull(row.Key2, newItem.Key2) &&
                      EqualOrBothNull(row.Key3, newItem.Key3) &&
                      EqualOrBothNull(row.Value, newItem.Value));
以下是对我的回答的几点评论的回复:

至少在VB.NET中,两个NullableOf T的比较总是计算为布尔值?如果其中至少有一个没有值,则值为Nothing:

不,a=b不仅仅是VB.NET中的赋值

运算符=是编译器在赋值和比较之间自动切换的上下文基

此外,在Quickwatch模式下,它总是被解析为比较

C的行为与VB不同:


刚刚检查过,在C中,simple==操作数的行为就像你在评论中看到的Ilya Ivanov和Konrad Morawski一样,因此在这个问题的场景中不需要使用HasValue。

如果row.Key2和newItem.Key2都为空,结果应该出现在tmp中吗?是的!我刚刚意识到第一个问题是错误的。如果一行1222,null,null,3。。。我查询的数据应该是returnedGreat。没有其他问题了?问题仍然存在…为什么不在int上使用==运算符呢?操作数。如果一个操作数为null,而另一个为null,则返回false。如果两者都为null-则返回true。如果两者都不为null-它将比较值。如果两者都为null,则不返回true!Console.WriteLine null==null//符合事实的我遗漏了什么吗?是的,但是两个Int32?这两个null的行为不一样,因为它们是引用,而不是基元类型。您检查过吗??Console.WriteLineint?null==int?null;//符合事实的可为空的a=空;可空b=空;Console.WriteLinea==b;提供相同的效果您不需要函数来比较空值。如果添加值计算。。。这就是我需要的!你能解释一下|和&在我们的例子中是什么意思吗?因为HasValue和comparison是布尔操作数,所以使用位运算符&、|是没有意义的。您应该真正使用标准的布尔运算符,请参见此处:。无论如何,正如我在回答“编辑2”结尾所写的那样,您可以简单地使用==而无需检查变量是否为hasValue,至少这对C是有效的。
object tmp= model.table.FirstOrDefault(t => 
    t.Key1 == newItem.Key1 
    && ((!t.Key2.HasValue & !newItem.Key2.HasValue) 
        | t.Key2.Value == newItem.Key2.Value)                             
    && ((!t.Key3.HasValue & !newItem.Key3.HasValue) 
        | t.Key3.Value == newItem.Key3.Value) && t.Value == newItem.Value);
object tmp= model.table.FirstOrDefault(t => 
    t.Key1 == newItem.Key1 
    && ((!t.Key2.HasValue & !newItem.Key2.HasValue) 
        | t.Key2.Value == newItem.Key2.Value)                             
    && ((!t.Key3.HasValue & !newItem.Key3.HasValue) 
        | t.Key3.Value == newItem.Key3.Value) && t.Value == newItem.Value);