dotnet / dotnet/efcore

Null Coalesce Operator between two join variable - throws exceptions

Open
#27,386 1 comment 0 reactions 0 assignees View on GitHub
area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

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.

1. Sample Query
```C#
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,
};
```

2. Inline-ing the result of `let`
```C#
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,
};
```

2. Working query
```C#
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,
};
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.