问题
recordsList.ListOfRecords = new StudentRecordsBAL()
.GetStudentsList()
.Select(q => new StudentRecords()
{
_RollNumber = q._RollNumber,
_Class = q._Class,
_Name = q._Name,
_Address = q._Address,
_City = q._City,
_State = q._State,
_Subjects = q._Subject,
_AttendedDays = new AttendanceBAL()
.GetAttendanceListOf(q._RollNumber)
.Where(date => date != null)
.Select(date =>
new DateTime(date._Date.Year, date._Date.Month, date._Date.Day))
.Distinct()
.ToList(),
_AttendedSubjects = GetAttendedSubjects(q._RollNumber)
}).ToList();
The method, GetAttendanceListOf(q._RollNumber)
in above code will return a list of records from the database or "null" if there are no records present for the passed "roll-no". A linq query will be terminated generating error
"Value cannot be null".
Is there a way to handle this error and make LINQ jump to next step?
回答1:
_AttendedDays = new AttendanceBAL()
.GetAttendanceListOf(q._RollNumber)
.Where(date => date != null)
.Select(date => new DateTime(date._Date.Year, date._Date.Month, date._Date.Day))
.Distinct()
.ToList(),
The problem is with running Where()
on null instance. Possible solutions:
1) modify GetAttendanceListOf
to return an empty list if no attendance (good idea in general, as null object pattern is very often a life saver, and for collection, an empty collection is often semantically similar to null)
2) if you don't control that method, write a safe extension method which will return empty list in case of null, e.g.
List<AttendanceType> SafeAttendanceList(this AttendanceBALType bal, RollNumber rn)
{
return bal.GetAttendanceListOf(rn) ?? new List<AttendanceType>();
}
Then call it as:
_AttendedDays = new AttendanceBAL()
.SafeAttendanceListOf(q._RollNumber)
.Where(date => date != null)
回答2:
You can try
recordsList.ListOfRecords = new StudentRecordsBAL().GetStudentsList().Select(q =>
{
var attendanceList = new AttendanceBAL().GetAttendanceListOf(q._RollNumber);
if (attendanceList == null)
return null;
return new StudentRecords()
{
_RollNumber = q._RollNumber,
_Class = q._Class,
_Name = q._Name,
_Address = q._Address,
_City = q._City,
_State = q._State,
_Subjects = q._Subject,
_AttendedDays = attendanceList.Where(date => date != null).Select(date => new DateTime(date._Date.Year, date._Date.Month, date._Date.Day)).Distinct().ToList(),
_AttendedSubjects = GetAttendedSubjects(q._RollNumber)
};
}).Where(q => q != null).ToList();
This checks that you do not do a Where
operation on a null object and filter out any null results.
回答3:
Linq ToList() will return an empty list if there are no results. The error might comes from elsewhere.
I would recommand you to use methods to create your objects, it will make your query easier to read and to debug. I would recommand that you do it in multiple steps to determine what is getting null and where exactly it fails to execute.
The error might comes from GetAttendanceListOf(), when having methods returning IList or IEnumerable, you should return an empty list if there is no results, it will prevent you from validating every time if it's null or not.
回答4:
As suggested by @Zdeslav Vojkovic modify GetAttendanceListOf
to return empty list if null or do something like:
_AttendedDays = (new AttendanceBAL() .GetAttendanceListOf(q._RollNumber) ?? Enumerator.Empty<typeofrecord>()) .Where(date => date != null) .Select(date => new DateTime(date._Date.Year, date._Date.Month, date._Date.Day)) .Distinct() .ToList(),
(you might be able to do it without the extra parenthesis)
回答5:
For a quick fix, Modify this line
_AttendedDays = new AttendanceBAL().GetAttendanceListOf(q._RollNumber).Where...
To this
_AttendedDays = (new AttendanceBAL().GetAttendanceListOf(q._RollNumber)??new List()).Where...
来源:https://stackoverflow.com/questions/15948369/how-to-handle-null-values-in-linq