2012-09-01 44 views
4

我有以下代码:如何检查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检查代码 以检查这两个个案。

回答

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); 
} 
+0

谢谢。这很好。几个拼写错误与Exeception :-) – Angela

+1

我会抛弃'Exception.Message'检查。如果某个地方的异常将其消息设置为空,我想知道该错误,所以我可以在源代码中追踪它。 –

2

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

+0

如果'error'为null会怎么样? –

+0

然后再添加到我之前,我回答了 –

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); 
1

要过滤出空值,然后.Where(error => error.Exception != null)(该Exception对象应该始终有一个非空的消息,所以我就当检测和修复那里,如果有异常的错误)。

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