Skip to content
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

Update from ef 6 to ef 7. Error getting base type entities where one child has a required navigation property #31107

Closed
Symasoiti97 opened this issue Jun 20, 2023 · 1 comment · Fixed by #31950
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression type-bug
Milestone

Comments

@Symasoiti97
Copy link

Symasoiti97 commented Jun 20, 2023

Bug

Retrieving entities of the base type where one child has a required navigation property throws a SqlNullValuException. Because not all entities have a required navigation property. Property.IsNullable is expected to be true when reading properties navigation.

Source code

Stack traces

System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
   at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
   at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()
   at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
   at lambda_method62(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
   at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
   at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()
   at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
   at lambda_method62(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()

Verbose output

Need to run test

C:\Program Files\dotnet\dotnet.exe exec  --runtimeConfig E:\Work\projects\EF.HierarchyWithOwnsOne\Tests\bin\Debug\net6.0\Tests.runtimeconfig.json --depsfile E:\Work\projects\EF.HierarchyWithOwnsOne\Tests\bin\Debug\net6.0\Tests.deps.json "C:\Program Files\JetBrains\Rider\r2r\2023.1.2R\6B49094255C5915777A714B5EEA9433\TestRunner\netcoreapp3.0\ReSharperTestRunner.dll" --parentProcessId 65984 -p 62324 -r 6c65adf1-fb86-41e5-8d68-82986246c9e9
...
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [e].[Id], [e].[Discriminator], [e].[Name], [c].[Id], [c].[Child1EntityId], [c].[Name]
      FROM [Entities] AS [e]
      LEFT JOIN [Child1EntityData] AS [c] ON [e].[Id] = [c].[Child1EntityId]
fail: Microsoft.EntityFrameworkCore.Query[10100]
      An exception occurred while iterating over the results of a query for context type 'DataAccess.AppDbContext'.
      System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
         at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
         at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()
         at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
         at lambda_method62(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
         at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
      System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
         at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
         at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()
         at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
         at lambda_method62(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
         at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()

Temporary solution

Have options:

  • Set navigation property as nullable
  • Add <entityBuilder>.Metadata.IsRequiredDependent = false; to navigation configuration

Provider and version information

EF Core version: 7.0.5
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 6.0

@ajcvickers
Copy link
Member

Note for triage: still fails on latest daily.

Minimal repro:

using (var context = new SomeDbContext())
{
    await context.Database.EnsureDeletedAsync();
    await context.Database.EnsureCreatedAsync();

    context.Add(new Child2Entity { Id = Guid.NewGuid(), Name = "Name" });
    context.SaveChanges();

    context.Set<BaseEntity>().ToList();
}

using (var context = new SomeDbContext())
{
}

public class SomeDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer(@"Data Source=(LocalDb)\MSSQLLocalDB;Database=AllTogetherNow")
            .LogTo(Console.WriteLine, LogLevel.Information)
            .EnableSensitiveDataLogging();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BaseEntity>();
        modelBuilder.Entity<Child1Entity>(b =>
        {
            b.OwnsOne(entity => entity.Data, builder =>
            {
                builder.ToTable("Child1EntityData");
                builder.WithOwner().HasForeignKey("Child1EntityId");
            });

        });

        modelBuilder.Entity<Child2Entity>();
    }
}

public abstract class BaseEntity
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public sealed class Child1Data
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public sealed class Child1Entity : BaseEntity
{
    public Child1Data Data { get; private set; } = null!;
}

public sealed class Child2Entity : BaseEntity
{
}

Output:

info: 6/21/2023 19:50:07.997 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (39ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
info: 6/21/2023 19:50:08.067 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      IF SERVERPROPERTY('EngineEdition') <> 5
      BEGIN
          ALTER DATABASE [AllTogetherNow] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
      END;
info: 6/21/2023 19:50:08.081 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      DROP DATABASE [AllTogetherNow];
info: 6/21/2023 19:50:08.213 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (96ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      CREATE DATABASE [AllTogetherNow];
info: 6/21/2023 19:50:08.245 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (31ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      IF SERVERPROPERTY('EngineEdition') <> 5
      BEGIN
          ALTER DATABASE [AllTogetherNow] SET READ_COMMITTED_SNAPSHOT ON;
      END;
info: 6/21/2023 19:50:08.248 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
info: 6/21/2023 19:50:08.326 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [BaseEntity] (
          [Id] uniqueidentifier NOT NULL,
          [Name] nvarchar(max) NOT NULL,
          [Discriminator] nvarchar(13) NOT NULL,
          CONSTRAINT [PK_BaseEntity] PRIMARY KEY ([Id])
      );
info: 6/21/2023 19:50:08.329 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [Child1EntityData] (
          [Child1EntityId] uniqueidentifier NOT NULL,
          [Id] uniqueidentifier NOT NULL,
          [Name] nvarchar(max) NOT NULL,
          CONSTRAINT [PK_Child1EntityData] PRIMARY KEY ([Child1EntityId]),
          CONSTRAINT [FK_Child1EntityData_BaseEntity_Child1EntityId] FOREIGN KEY ([Child1EntityId]) REFERENCES [BaseEntity] ([Id]) ON DELETE CASCADE
      );
info: 6/21/2023 19:50:08.505 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (18ms) [Parameters=[@p0='8d571c82-0104-415c-b86a-44e16d5ff363', @p1='Child2Entity' (Nullable = false) (Size = 13), @p2='Name' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET IMPLICIT_TRANSACTIONS OFF;
      SET NOCOUNT ON;
      INSERT INTO [BaseEntity] ([Id], [Discriminator], [Name])
      VALUES (@p0, @p1, @p2);
info: 6/21/2023 19:50:08.736 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [b].[Id], [b].[Discriminator], [b].[Name], [c].[Child1EntityId], [c].[Id], [c].[Name]
      FROM [BaseEntity] AS [b]
      LEFT JOIN [Child1EntityData] AS [c] ON [b].[Id] = [c].[Child1EntityId]
fail: 6/21/2023 19:50:08.754 CoreEventId.QueryIterationFailed[10100] (Microsoft.EntityFrameworkCore.Query)
      An exception occurred while iterating over the results of a query for context type 'SomeDbContext'.
      System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
         at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
         at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()
         at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
         at lambda_method40(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
         at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
Unhandled exception. System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
   at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
   at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()
   at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
   at lambda_method40(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Program.<Main>$(String[] args) in C:\local\code\AllTogetherNow\Daily\Daily.cs:line 21
   at Program.<Main>(String[] args)

@ajcvickers ajcvickers changed the title Migration error from ef 6 to ef 7. Error getting base type entities where one child has a required navigation property Update from ef 6 to ef 7. Error getting base type entities where one child has a required navigation property Jul 8, 2023
@ajcvickers ajcvickers added this to the Backlog milestone Jul 8, 2023
@ajcvickers ajcvickers modified the milestones: Backlog, 7.0.x Oct 2, 2023
@AndriySvyryd AndriySvyryd added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 3, 2023
@AndriySvyryd AndriySvyryd removed their assignment Oct 3, 2023
@ajcvickers ajcvickers modified the milestones: 7.0.x, 7.0.13 Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants