EF 7.0.9 returns a non-null value despite explicitly selecting for a nullable value.
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
EF 7.0.9 returns a non-null value despite explicitly selecting for a nullable value.
Seems similar to https://github.com/dotnet/efcore/issues/26744
Here is a complete Console app repro:
### `Program.cs`
```C#
using Microsoft.EntityFrameworkCore;
// Reset DB
var db = new TestContext();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
// Add Customers
{
// #1 - customer with active plan
db.Add(new Customer { Id = 1, ServicePlan = new ServicePlan { TerminationDate = null } });
// #2 - customer with past plan
db.Add(new Customer { Id = 2, ServicePlan = new ServicePlan { TerminationDate = DateTime.Now.AddDays(-1) } });
// #3 - customer who never had a plan
db.Add(new Customer { Id = 3, ServicePlan = null });
db.SaveChanges();
}
// Test queries
// OK
var neverCustomers = db.Customers.Where(c => c.ServicePlan == null).ToList();
PrintCustomerIds(neverCustomers); // "3"
// OK
var customers = db.Customers.Where(c => c.ServicePlan != null).ToList();
PrintCustomerIds(customers); // "1, 2"
// OK
var pastCustomers = db.Customers.Where(c => c.ServicePlan.TerminationDate != null).ToList();
PrintCustomerIds(pastCustomers); // "2"
// OK
var validData = db.Customers
.Select(c => c.ServicePlan == null ? (bool?)null : c.ServicePlan.TerminationDate != null);
PrintNullableBools(validData); // OUTPUT: "False, True, Null"
// BUG. Should produce the same output as the previous query.
var badData = db.Customers
.Select(c => c.ServicePlan == null ? (bool?)null : c.ServicePlan.TerminationDate.HasValue);
PrintNullableBools(badData); // OUTPUT: "False, True, False". EXPECTED: "False, True, Null"
// Helpers
void PrintCustomerIds(IEnumerable customers)
=> Console.WriteLine(string.Join(", ", customers.Select(x => x.Id)));
void PrintNullableBools(IEnumerable data)
=> Console.WriteLine(string.Join(", ",
data.Select(b => b == null ? "Null" : b.ToString())));
// Model
public class Customer
{
public int Id { get; set; }
public ServicePlan? ServicePlan { get; set; }
}
public class ServicePlan
{
public int Id { get; set; }
public DateTime? TerminationDate { get; set; }
}
// DbContext
public class TestContext : DbContext
{
public DbSet Customers { get; set; }
public DbSet ServicePlans { get; set; }
public string DbPath { get; }
public TestContext()
{
var folder = Environment.SpecialFolder.LocalApplicationData;
var path = Environment.GetFolderPath(folder);
DbPath = Path.Join(path, "EfCoreNullableQuerying.db");
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite($"Data Source={DbPath}");
}
```
### `EfCoreNullableQuerying.csproj`
```
Exe
net7.0
enable
enable
```
Contributor guide
Assessment
This issue has not been assessed yet.