-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
File a bug
I have run into this problem when upgrading from 8.0.3 to 8.0.4.
I have a Parent type that contains an optional Child.
public class Parent
{
public int Id { get; set; }
public Child? Child { get; set; }
}
The Child contains a simple type, that is saved as a ComplexProperty.
public class Child
{
public int Id { get; set; }
public required Complex Complex { get; set; }
public bool Deleted { get; set; }
}
There is a QueryFilter defined for the Child (simple bool property "Deleted").
public class ApplicationDbContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base (options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating (modelBuilder);
modelBuilder.Entity<Child> ()
.ComplexProperty (x => x.Complex);
modelBuilder.Entity<Child> ().HasQueryFilter (x => !x.Deleted);
}
}
The Complex type contains a enum
.
public class Complex
{
public MyEnum Enum { get; set; }
}
public enum MyEnum
{
None = 0,
Enabled = 1,
}
When I now try to query the enum coming from the Parent type though the Child and Complex types, I want the result to be null
, if the (optional) Child is not set (is null
).
var my_enum = db_context.Parents
.Select (p => p.Child != null ? (MyEnum?)p.Child.Complex.Enum : null)
.FirstOrDefault ();
But i get a InvalidOperationException instead.
Downgrading back to 8.0.3 restores the expected behavior again.
Include your code
I have created a small solution with one console project to reproduce the problem:
efcore-enum-in-optional-complex-property-with-queryfilter-repro.zip
It creates a sqlite database (deleting any existing "test.db" file beforehand) so you should be able to just run it (again and again) to reproduce the exception.
Stack traces
Unhandled exception. System.InvalidOperationException: An error occurred while reading a database value. The expected type was 'efcore_enum_in_optional_complex_property_repro.Entites.MyEnum' but the actual value was null.
---> System.InvalidOperationException: The data is NULL at ordinal 0. This method can't be called on NULL values. Check using IsDBNull before calling.
at Microsoft.Data.Sqlite.SqliteValueReader.GetInt64(Int32 ordinal)
at Microsoft.Data.Sqlite.SqliteValueReader.GetInt32(Int32 ordinal)
at Microsoft.Data.Sqlite.SqliteDataReader.GetInt32(Int32 ordinal)
at lambda_method31(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
--- End of inner exception stack trace ---
at lambda_method31(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found)
at lambda_method32(Closure, QueryContext)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at Program.<<Main>$>g__Act|0_2(<>c__DisplayClass0_0&) in %path-to-repos%\efcore-enum-in-optional-complex-property-with-queryfilter-repro\efcore-enum-in-optional-complex-property-repro\Program.cs:line 49
at Program.<Main>$(String[] args) in %path-to-repos%\efcore-enum-in-optional-complex-property-with-queryfilter-repro\efcore-enum-in-optional-complex-property-repro\Program.cs:line 12
Include provider and version information
EF Core version: 8.0.4 (still works in 8.0.3)
Database provider: Microsoft.EntityFrameworkCore.Sqlite 8.0.4 (same error happens with Microsoft.EntityFrameworkCore.SqlServer 8.0.4)
Target framework: .NET 8.0
Operating system: Windows 11
IDE: Visual Studio 2022 17.9.5