更优雅的嵌套 Linq 查询解决方案?

More graceful solution to nested Linq queries?

我有一组嵌套的 linq 查询,用于从属性列表中获取 属性。它按原样运行良好,但有一个警告。我必须进行错误处理以防万一没有合适的匹配项。是否有类似的方法可以在不使用 try-catch 块的情况下完成以下代码的功能?

try
{
    organization =
    _orgs.FirstOrDefault(n => 
        n.OrganizationFields.FirstOrDefault(nn => 
            nn.Key == "customer_id").Value.ToString() == id);
}
catch (InvalidOperationException)
{
    return null;
}
catch (NullReferenceException)
{
    return null;
}

如果您使用的是 C# 6,则可以使用 Null Conditional Operator

organization =
_orgs?.FirstOrDefault(n => 
    n.OrganizationFields?.FirstOrDefault(nn => 
        nn.Key == "customer_id")?.Value.ToString() == id);

这是一个完整的程序,展示了它的实际应用

class Bar
{
    public string Text { get; set; }
}

class Foo
{
    public List<Bar> Bars { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo(); // Note that foo.Bars is still null

        string text = foo.Bars?.FirstOrDefault()?.Text;

        Console.WriteLine(text);
    }
}

我不确定你为什么需要捕捉 InvalidOperationException,所以我会忽略它。关于 NullReferenceException,我假设它只能由 FirstOrDefault(...).Value 调用生成(如果您遵循最佳实践,_orgsn.OrganizationFields 或 none 或Value 应该是 null)。

如果以上假设正确,下面的示例代码应该是等效的w/o需要异常处理程序

organization = _orgs.FirstOrDefault(n => n.OrganizationFields
    .Any(nn => nn.Key == "customer_id" && nn.Value.ToString() == id));

根据您的评论,如果 Value 可以是 null,那么要么在 C#6 中使用 nn.Value?.ToString() == ...,要么在 C#6 之前的版本中使用 nn.Value != null && nn.Value.ToString() == ...