diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index 3b665cb1376..3abcdc12f76 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -29,6 +29,8 @@ public sealed partial class SelectExpression : TableExpressionBase private static readonly bool UseOldBehavior30273 = AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue30273", out var enabled30273) && enabled30273; + private static readonly bool UseOldBehavior31107 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31107", out var enabled31107) && enabled31107; private static readonly IdentifierComparer IdentifierComparerInstance = new(); @@ -2637,7 +2639,9 @@ static IReadOnlyDictionary GetPropertyExpressions( var parentNullable = identifyingColumn.IsNullable; var pkColumnsNullable = parentNullable || (derivedType && ownerType.GetMappingStrategy() != RelationalAnnotationNames.TphMappingStrategy); - var newColumnsNullable = pkColumnsNullable || !navigation.ForeignKey.IsRequiredDependent; + var newColumnsNullable = pkColumnsNullable + || !navigation.ForeignKey.IsRequiredDependent + || (derivedType && !UseOldBehavior31107); if (derivedTpt) { principalMappings = principalMappings.Except(ownerType.BaseType!.GetViewOrTableMappings().Select(e => e.Table)); diff --git a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs index f559e7266ea..edb9680fb74 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs @@ -408,7 +408,7 @@ public void Seed() } } - public class RotRutCase + protected class RotRutCase { public int Id { get; set; } public string Buyer { get; set; } @@ -416,19 +416,19 @@ public class RotRutCase public Rut Rut { get; set; } } - public class Rot + protected class Rot { public int? ServiceType { get; set; } public string ApartmentNo { get; set; } } - public class RotDto + protected class RotDto { public int? MyServiceType { get; set; } public string MyApartmentNo { get; set; } } - public class Rut + protected class Rut { public int? Value { get; set; } } @@ -498,14 +498,14 @@ public void Seed() } } - public class Monarch30358 + protected class Monarch30358 { public int Id { get; set; } public string Name { get; set; } public string RulerOf { get; set; } } - public class Magus30358 + protected class Magus30358 { public int Id { get; set; } public string Name { get; set; } @@ -513,11 +513,69 @@ public class Magus30358 public MagicTool30358 ToolUsed { get; set; } } - public class MagicTool30358 + protected class MagicTool30358 { public string Name { get; set; } } + protected abstract class BaseEntity31107 + { + public Guid Id { get; set; } + } + + protected sealed class ChildData31107 + { + public Guid Id { get; set; } + } + + protected sealed class Child1Entity31107 : BaseEntity31107 + { + public ChildData31107 Data { get; set; } + } + + protected sealed class Child2Entity31107 : BaseEntity31107 + { + } + + [ConditionalFact] + public async Task Can_have_required_owned_type_on_derived_type() + { + var contextFactory = await InitializeAsync(seed: c => c.Seed()); + using var context = contextFactory.CreateContext(); + + context.Set().ToList(); + } + + private class RequiredNavigationContext : DbContext + { + public RequiredNavigationContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(); + modelBuilder.Entity(b => + { + b.OwnsOne(entity => entity.Data, builder => + { + builder.ToTable("Child1EntityData"); + builder.WithOwner().HasForeignKey("Child1EntityId"); + }); + b.Navigation(e => e.Data).IsRequired(); + }); + + modelBuilder.Entity(); + } + public void Seed() + { + Add(new Child2Entity31107 { Id = Guid.NewGuid() }); + + SaveChanges(); + } + } + protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => base.AddOptions(builder).ConfigureWarnings( c => c