@@ -2053,10 +2053,11 @@ protected static EntityEntry<TEntity> TrackFromQuery<TEntity>(DbContext context,
20532053 protected virtual Task ExecuteWithStrategyInTransactionAsync (
20542054 Func < DbContext , Task > testOperation ,
20552055 Func < DbContext , Task > ? nestedTestOperation1 = null ,
2056- Func < DbContext , Task > ? nestedTestOperation2 = null )
2056+ Func < DbContext , Task > ? nestedTestOperation2 = null ,
2057+ Func < DbContext , Task > ? nestedTestOperation3 = null )
20572058 => TestHelpers . ExecuteWithStrategyInTransactionAsync (
20582059 CreateContext , UseTransaction ,
2059- testOperation , nestedTestOperation1 , nestedTestOperation2 ) ;
2060+ testOperation , nestedTestOperation1 , nestedTestOperation2 , nestedTestOperation3 ) ;
20602061
20612062 protected virtual void UseTransaction ( DatabaseFacade facade , IDbContextTransaction transaction )
20622063 {
@@ -2397,6 +2398,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con
23972398 } ) ;
23982399 } ) ;
23992400 } ) ;
2401+
2402+ modelBuilder . Entity < EntityWithOptionalMultiPropComplex > ( b =>
2403+ {
2404+ b . ComplexProperty ( e => e . ComplexProp ) ;
2405+ } ) ;
24002406 }
24012407 }
24022408
@@ -4373,4 +4379,72 @@ protected static FieldPubWithReadonlyStructCollections CreateFieldCollectionPubW
43734379 ] ,
43744380 FeaturedTeam = new TeamReadonlyStruct ( "Not In This Lifetime" , [ "Slash" , "Axl" ] )
43754381 } ;
4382+
4383+ [ ConditionalTheory ( ) , InlineData ( false ) , InlineData ( true ) ]
4384+ public virtual async Task Can_save_default_values_in_optional_complex_property_with_multiple_properties ( bool async )
4385+ {
4386+ await ExecuteWithStrategyInTransactionAsync (
4387+ async context =>
4388+ {
4389+ var entity = Fixture . UseProxies
4390+ ? context . CreateProxy < EntityWithOptionalMultiPropComplex > ( )
4391+ : new EntityWithOptionalMultiPropComplex ( ) ;
4392+
4393+ entity . Id = Guid . NewGuid ( ) ;
4394+ entity . ComplexProp = null ;
4395+
4396+ _ = async ? await context . AddAsync ( entity ) : context . Add ( entity ) ;
4397+ _ = async ? await context . SaveChangesAsync ( ) : context . SaveChanges ( ) ;
4398+
4399+ Assert . Null ( entity . ComplexProp ) ;
4400+ } ,
4401+ async context =>
4402+ {
4403+ var entity = async
4404+ ? await context . Set < EntityWithOptionalMultiPropComplex > ( ) . SingleAsync ( )
4405+ : context . Set < EntityWithOptionalMultiPropComplex > ( ) . Single ( ) ;
4406+
4407+ Assert . Null ( entity . ComplexProp ) ;
4408+
4409+ // Set the complex property with default values
4410+ entity . ComplexProp = new MultiPropComplex
4411+ {
4412+ IntValue = 0 ,
4413+ BoolValue = false ,
4414+ DateValue = default
4415+ } ;
4416+
4417+ _ = async ? await context . SaveChangesAsync ( ) : context . SaveChanges ( ) ;
4418+
4419+ Assert . NotNull ( entity . ComplexProp ) ;
4420+ Assert . Equal ( 0 , entity . ComplexProp . IntValue ) ;
4421+ Assert . False ( entity . ComplexProp . BoolValue ) ;
4422+ Assert . Equal ( default , entity . ComplexProp . DateValue ) ;
4423+ } ,
4424+ async context =>
4425+ {
4426+ var entity = async
4427+ ? await context . Set < EntityWithOptionalMultiPropComplex > ( ) . SingleAsync ( )
4428+ : context . Set < EntityWithOptionalMultiPropComplex > ( ) . Single ( ) ;
4429+
4430+ // Complex types with more than one property should materialize even with default values
4431+ Assert . NotNull ( entity . ComplexProp ) ;
4432+ Assert . Equal ( 0 , entity . ComplexProp . IntValue ) ;
4433+ Assert . False ( entity . ComplexProp . BoolValue ) ;
4434+ Assert . Equal ( default , entity . ComplexProp . DateValue ) ;
4435+ } ) ;
4436+ }
4437+
4438+ public class EntityWithOptionalMultiPropComplex
4439+ {
4440+ public virtual Guid Id { get ; set ; }
4441+ public virtual MultiPropComplex ? ComplexProp { get ; set ; }
4442+ }
4443+
4444+ public class MultiPropComplex
4445+ {
4446+ public int IntValue { get ; set ; }
4447+ public bool BoolValue { get ; set ; }
4448+ public DateTimeOffset DateValue { get ; set ; }
4449+ }
43764450}
0 commit comments