首页 > 解决方案 > 在 LINQ 内部连接中保留空值

问题描述

此代码执行内部连接specialthings然后生成things相应匹配项的索引:

object[] special = {      'b',    null, 5.0f,      "notme" };
object[] things  = { "a", 'b', 3, null, 5.0f, 6.0          };

var specialThingIndices = from tn in things.Select((t,n) => (t,n)) 
                          join s in special on tn.t equals s
                          select tn.n;

foreach (var n in specialThingIndices)
    Console.WriteLine($"[{n}] = {Convert.ToString(things[n])}, {things[n] is null}");

它输出:

[1] = b, False
[4] = 5, False

但是,null出现在两个数组中,我不想跳过它。所以我希望它输出的是:

[1] = b, False
[3] = , True
[4] = 5, False

为什么它看不到nulls,我怎样才能让它保留它们?

我尝试在各个地方手动申请DefaultIfEmpty(),但没有成功。我也尝试过替换equals==但我想那不是有效的语法。我想不出别的。

可运行的示例在这里

标签: c#linqnullc#-8.0

解决方案


如果为 null,您可以选择默认值,例如"<null>"字符串。

...
object[] special = { 'b', null, 5.0f, "notme" };
object[] things = { "a", 'b', 3, null, 5.0f, 6.0 };

var specialThingIndices = from tn in things.Select(x => x ?? "<null>").Select((t, n) => (t, n))
                          join s in special.Select(x => x ?? "<null>") on tn.t equals s
                          select tn.n;

foreach (var n in specialThingIndices)
    Debug.WriteLine($"[{n}] = {Convert.ToString(things[n])}, {things[n] is null}");
...

Where使用而不是编辑 另一个解决方案join

...
object[] special = { 'b', null, 5.0f, "notme" };
object[] things = { "a", 'b', 3, null, 5.0f, 6.0 };

var specialThingIndices = from tn in things.Select((t, n) => (t, n))
                          where special.Any(s => Equals(s, tn.t))
                          select tn.n;

foreach (var n in specialThingIndices)
    Debug.WriteLine($"[{n}] = {Convert.ToString(things[n])}, {things[n] is null}");
...

推荐阅读