-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to coalesce values when navigating nullable relationships? #33336
Comments
I might be missing something, but the below seem to work just fine - I'm not seeing a CS0019: Value = f.Other.Value ?? "default" // NOPE: CS0019 Operator '??' can't be applied
Value = f.Other!.Value ?? "default" // NOPE: Same as above I'm also not sure why there would be one - Value is a string (reference type). |
@roji Forgot to mention, we have nullable reference types enabled in our |
So do I. The first line indeed generates a CS8602 (dereference of a possibly null reference), but the second one with the bang doesn't generate any warnings. See my complete console program below (adapter from your code). Attempted repro#nullable enable
await using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
// Now we try to query...
var query =
from f in context.Firsts
select new {
Id = f.Id,
Value = f.Other.Value ?? "default", // warning CS8602: Dereference of a possibly null reference
Value2 = f.Other!.Value ?? "default" // no warning
};
public class BlogContext : DbContext
{
public DbSet<First> Firsts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
public class First {
public int Id { get; set; }
public Second? Other { get; set; }
}
public class Second {
public int Id { get; set; }
public string Value { get; set; } = "";
} |
@roji Okay, narrowing down on the scope of the issue... try changing the type of |
Right, you cannot apply the C# coalescing operator to a (non-nullable) value type: context.Firsts.Where(f => f.Other.Value ?? 9 == 10); And you indeed can't use the null-coalescing operator to turn it into an |
I'm going to go ahead and close this as there isn't anything we can do here, except for getting expression tree support to support newer C# features. But please feel free to post back with further questions/suggestions. |
Maybe the documentation on nullable support in EF Core could note something about this? It's partially related and partially not, because it's the interaction of the nullable reference type in the foreign key reference and the property not being a reference type that makes things tricky. I don't expect anything could actually be done until |
We haven't seen complaints about this particular problem - I think the compilation errors generally guide people in the right direction here. But if more people express confusion we can definitely add a note to the docs, absolutely. |
Ask a question
So, we're not allowed to use the null-propagation operator
?.
in expression trees--annoying, but I assume there's a good reason. As a result, the documentation says we have to lie using the null-forgiving operator!.
to get our code translated to SQL. However, now, as far as C# is concerned, the value can't be null, even though it really can be--which means we can't use the??
coalesce operator any more to coalesce the null value away! Is there a solution for this? If there was anEF.Functions.Coalesce()
function we could use, then at least we could have a way to useCOALESCE
directly, but since that doesn't exist, there doesn't seem to be a clean solution to this.Include your code
Include provider and version information
EF Core version: 6.0.27
Database provider: NPGSQL
Target framework: .NET 6.0
Operating system: Windows 10
IDE: Visual Studio 2022 17.9.3
The text was updated successfully, but these errors were encountered: