[英]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.