Essentially, I'm trying to exclude entities with a null child object from a query result. I'd like to do this using in the most efficient way possible, loading the smallest amount of data necessary.
I am working with a database that doesn't enforce referential integrity; some Pupils have been deleted, so, unfortunately, some of the Reports that do specify PupilID no longer have a matching pupil. I want to exclude such reports.
My original problem method is further below, but here is my core problem.
var test1 =
DbContext.Report
.Where(x => x.Pupil != null).ToList();
var test2 =
DbContext.Report
.Include(x => x.Pupil)
.Where(x => x.Pupil != null).ToList();
if (test1.Count(x => x.Pupil == null) > 0)
{
var bp = "hit"; // I know this doesn't work
}
if (test2.Count(x => x.Pupil == null) > 0)
{
var bp = "hit"; // But why doesn't this? And how can I make it work...
}
if (test1.Where(x => x.Pupil != null).Count(x => x.Pupil == null) > 0)
{
var bp = "not hit"; // Without having to do this
}
I assume it's some issue to do with EF lazy loading, but I've tried explicitly loading and including them to no avail; the only thing that works is calling.ToList() on the entire query which will evaluate the proxies and allow me to exclude them correctly, however, to do this it'll load data I do not need just to throw it away. Is there any way around this?
Original problem method:
public IEnumerable<Report> GetCurrentReportsForStaffByUsername(string username)
{
var staffId =
GetStaffIdFromUsername(username);
var query = (
from reports in this.DbContext.Reports.Include(x => x.Pupil).Where(x => x.Pupil != null)
where reports.StaffId == staffId
&& reports.Pupil != null
select reports)
.Include(r => r.Pupil)
.Where(r => r.Pupil != null);
if (query.Any(q => q.Pupil == null))
{
var error = "how?!?!?!?!?!?!?!?"; // <-- Hits this
}
if (query.ToList().Any(q => q.Pupil == null))
{
var error = "really?";
}
return query;
}
Thank-you for taking the time :)