如何检查linq查询中的null?

时间:2012-09-01 09:09:46

标签: c# linq

我有以下代码:

protected IEnumerable<string> GetErrorsFromModelState() {

    var exceptions = ModelState.SelectMany(x => x.Value.Errors
        .Select(error => error.Exception.Message));

    var errors = ModelState.SelectMany(x => x.Value.Errors
        .Select(error => error.ErrorMessage));

    return exceptions.Union(errors);
}

如果符合以下情况,有没有办法可以阻止这种情况给出nullReference异常:

error.Exception is null  or if error.Exception.Message is null

两种情况都给我带来了问题,我不知道如何编写代码 使用IsNullOrEmpty检查两个个案。

4 个答案:

答案 0 :(得分:2)

在您选择之前添加.Where(error.Exception != null && error.Exception.Message != null)只包含您想要的值不是null的那些。

答案 1 :(得分:2)

怎么样

protected IEnumerable<string> GetErrorsFromModelState()
{        
    var exceptions = ModelState.SelectMany(x => x.Value.Errors
                            .Where(error => (error != null) && 
                                            (error.Exception != null) &&
                                            (error.Exception.Message != null))
                            .Select(error => error.Exception.Message));

    var errors = ModelState.SelectMany(x => x.Value.Errors
                            .Where(error => (error != null) && 
                                            (error.ErrorMessage != null))
                            .Select(error => error.ErrorMessage));

    return exceptions.Union(errors);
}

答案 2 :(得分:2)

您可以使用May be Monad,首先编写静态类并放置With 该类中的扩展方法,然后只需使用With方法。在链接中还有一些其他类似的类型也很有帮助。

public static TResult With<TInput, TResult>(this TInput o, 
       Func<TInput, TResult> evaluator)
       where TResult : class where TInput : class
{
  if (o == null) return null;
  return evaluator(o);
}

简单地使用它:

var exceptions = ModelState.SelectMany(x => x.With(y=>y.Value).With(z=>z.Errors))
        .Select(error => error.With(e=>e.Exception).With(m=>m.Message));

更新:为了更清晰(类似的示例也存在于链接中),假设您有Person类层次结构:

public class Person
{
   public Address Adress{get;set;}
}

public class Address
{
   public string PostCode{get;set;}
}

现在你想获得人的相关邮政编码而你不知道输入人是否为空:

var postCode = 
// this gives address or null, if either person is null or its address
person.With(x=>x.Address) 
// this gives post code or returns null, 
// if previous value in chain is null or post code is null 
      .With(x=>x.PostCode);

答案 3 :(得分:1)

要过滤掉空值,那么.Where(error => error.Exception != null)Exception对象应始终具有非空消息,因此如果存在异常,我会将其视为检测并修复的错误)。

在这种情况下表现不同,例如.Select(error => error.Exception == null ? "No Error" : error.Exception.Message)