Null Coalesce Operator between two join variable - throws exceptions
Ok, as a sample (Code 1#) I just share part of my code to see how the issue has happened, and why we may need it?
In the following query (Code 1#) as you can see, I used the let operator, which first I thought, hey the issue is for using let as it was previously reported to cause an issue... but later, after inline-ing (Code 2#) the result of the let operator, I noticed the issue is still persists
As you can see I have two join, and I use let to decrease complexity, duplicate null checking and improve the readability of code.
But both codes failed, and unfortunately as we are near the deadline, I'm afraid I cannot provide you stack trace; but the error was not reporting anything meaningful, and the query worked before I start to filter data, so my suggestion is at some point when it fails to bring data, the (x??y).Data will face null reference exception of some kind, but EF handles x.Data ?? y.Data just fine as the last query succeed (Code 3#) and as we do not have the Null Propagation operator (?,) in LINQ queries either it is a bug, or same to DefaultIfEmpty() it just needs a replacement, or the best solution is that Null Coalesce operator (??) work as expected even in such cases.
- Sample Query
from person in GetQuery(DbContext.People)
join personLocalization in DbContext.PersonLocalizations
on new { person.Id, RequestDataProvider.Culture }
equals new { Id = personLocalization.LocalizableId, personLocalization.Culture }
into personLocalizations
from personLocalization in personLocalizations.DefaultIfEmpty()
join businessPersonLocalization in DbContext.PersonLocalizations
on new { person.Id, Culture = RequestDataProvider.MainSetting.DefaultCulture }
equals new { Id = businessPersonLocalization.LocalizableId, businessPersonLocalization.Culture }
into businessPersonLocalizations
from businessPersonLocalization in businessPersonLocalizations.DefaultIfEmpty()
let currentPersonLocalization = personLocalization ?? businessPersonLocalization
select new PersonListResponse
{
Title = currentPersonLocalization.Title,
};
- Inline-ing the result of
let
from person in GetQuery(DbContext.People)
join personLocalization in DbContext.PersonLocalizations
on new { person.Id, RequestDataProvider.Culture }
equals new { Id = personLocalization.LocalizableId, personLocalization.Culture }
into personLocalizations
from personLocalization in personLocalizations.DefaultIfEmpty()
join businessPersonLocalization in DbContext.PersonLocalizations
on new { person.Id, Culture = RequestDataProvider.MainSetting.DefaultCulture }
equals new { Id = businessPersonLocalization.LocalizableId, businessPersonLocalization.Culture }
into businessPersonLocalizations
from businessPersonLocalization in businessPersonLocalizations.DefaultIfEmpty()
select new PersonListResponse
{
Title = (personLocalization ?? businessPersonLocalization).Title,
};
- Working query
from person in GetQuery(DbContext.People)
join personLocalization in DbContext.PersonLocalizations
on new { person.Id, RequestDataProvider.Culture }
equals new { Id = personLocalization.LocalizableId, personLocalization.Culture }
into personLocalizations
from personLocalization in personLocalizations.DefaultIfEmpty()
join businessPersonLocalization in DbContext.PersonLocalizations
on new { person.Id, Culture = RequestDataProvider.MainSetting.DefaultCulture }
equals new { Id = businessPersonLocalization.LocalizableId, businessPersonLocalization.Culture }
into businessPersonLocalizations
from businessPersonLocalization in businessPersonLocalizations.DefaultIfEmpty()
select new PersonListResponse
{
Title = personLocalization.Title ?? businessPersonLocalization.Title,
};
Can you share a small repro project?