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

时间:2016-01-07 22:23:24

标签: c# linq refactoring

我有一组嵌套的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;
}

2 个答案:

答案 0 :(得分:3)

如果您使用的是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);
    }
}

答案 1 :(得分:1)

我不确定你为什么需要抓住InvalidOperationException,所以我会忽略它。那么NullReferenceException呢,我认为它只能通过FirstOrDefault(...).Value调用生成(如果您遵循最佳做法,则不会_orgsn.OrganizationFields或{{1}应该是Value)。

如果上述假设是正确的,则以下内容应相当于不需要异常处理程序的示例代码

null

根据您的评论,如果organization = _orgs.FirstOrDefault(n => n.OrganizationFields .Any(nn => nn.Key == "customer_id" && nn.Value.ToString() == id)); 可以是Value,那么请在C#6中使用null,或在C#6之前使用nn.Value?.ToString() == ...