繁体   English   中英

避免查询中引发的EF中的空异常

[英]Avoiding null exception in EF that is thrown by your query

我有这样的查询:

        result =
            firstIdeaRepository.FindBy(
                i => i.FirstIdeaState == FirstIdeaState && i.Date >= start && i.Date <= end)
                               .AsEnumerable()
                               .Select(j => new RptListOfCompanyBasedOnFirstIdeaState()
                                   {
                                       Name =
                                           companyRepository.FindBy(i => i.UserId == j.UserId)
                                                            .FirstOrDefault()
                                       DateOfMeeting =
                                           calenderRepository.ConvertToPersianToShow(
                                               meetingReposiotry.FindBy(s => s.FirstIdeaId == j.Id)
                                                                .FirstOrDefault()
                                                                .Date),
                                       DateOfExit =
                                           calenderRepository.ConvertToPersianToShow(j.DateOfExit.Value),
                                       ReasonOfExit = j.ReasonOfExit,
                                   }).ToList();

    return result;

如您所见,我使用FirstOrDefault()j.DateOfExit.Value ,有时我的Date没有任何值,或者有时我的其他变量也为null,因为我使用firstordefaut()就像

companyRepository.FindBy(i => i.UserId == j.UserId).FirstOrDefault().

所以我的查询抛出一个null异常,并且无法创建结果,我该如何处理该异常,例如,如果.NET检测到null值默认情况下将其忽略或对该值使用默认值?

最好的祝福。

由于您使用的是可为空的日期,因此您可以尝试按具有日期的值进行过滤,例如:

.FindBy(s => s.FirstIdeaId == j.Id && s.Date.HasValue)

这将确保您不会得到任何日期为空的记录。

正如我在评论中提到的那样,其他案例需要逐案处理。 从显示的代码来看,也许可以将Name处理为:

 Name = companyRepository.FindBy(i => i.UserId == j.UserId).FirstOrDefault() ?? "anonymous";

等等。

另一个例子:

如果即使DateOfMeeting为null,也要获取记录,请在后续部分中添加对HasValue的检查,或将其默认为某个日期:

 DateOfExit = j.DateOfExit.HasValue ? 
              callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value)
              : (DateTime)null,   // you need to make `DateOfExit` nullable and then handle that downstream

// or (default with current date)
 DateOfExit = j.DateOfExit.HasValue ?
              callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value) 
              : callenderRepository.ConvertToPersianToShow(DateTime.Now),

// or (default with empty date)
 DateOfExit = j.DateOfExit.HasValue ?
              callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value) 
              : callenderRepository.ConvertToPersianToShow(new DateTime()),

这个故事的寓意:找出默认值应在空的情况下什么 ,然后打电话时替代品相应查询FirstOrDefault()

我将进行以下更改:

result =
    firstIdeaRepository.FindBy(
        i => i.FirstIdeaState == FirstIdeaState && i.Date >= start && i.Date <= end)
            .AsEnumerable()
            .Select(j => new RptListOfCompanyBasedOnFirstIdeaState()
            {
                Name =
                    companyRepository.FindBy(i => i.UserId == j.UserId)
                        .FirstOrDefault()
                DateOfMeeting =
                    callenderRepository.ConvertToPersianToShow(
                        meetingReposiotry.FindBy(s => s.FirstIdeaId == j.Id)
                            // project a new sequence first, before calling `FirstOrDefault`:
                            .Select(s => s.Date)
                            .FirstOrDefault(),
                DateOfExit =
                    j.DateOfExit.HasValue ? 
                        callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value) :
                        null,                       
                   ReasonOfExit = j.ReasonOfExit,
               }).ToList();

当您使用FirstOrDefault ,有可能返回null (对于引用类型),因此您需要在代码中进行规划。

例如,在分配DateOfMeeting ,可以在使用.FirstOrDefault之前投影结果(使用.Select ),这样就永远不会访问可能为空值的Date属性。

至于DateOfExit ,我使用了条件运算符来确定是否完全调用calendarRepository的方法。 假定DateOfExit是可为空的。

无关 :“日历”的拼写是一个“ l”而不是两个。

最广泛的解决方案是将空对象的概念与查询中的DefaultIfEmpty <T>(T DefaultValue)方法一起使用。 一个例子是:

var defaultMeeting = new Meeting() { Date = new DateTime() };

var dateOfMeeting = meetingRepository.FindBy(s => s.FirstIdeaId == j.Id)
        .DefaultIfEmpty(defaultMeeting)
        .FirstOrDefault()
        .Date;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM