@@ -348,4 +348,110 @@ public async Task InsertEntities_WithConflict_MultipleColumns(InsertStrategy str
348348 Assert . Contains ( insertedEntities , e => e . Name == $ "{ _run } _Entity2") ;
349349 Assert . Contains ( insertedEntities , e => e . Name == $ "{ _run } _Entity1 - Conflict" && e . Price == 0 ) ;
350350 }
351+
352+ [ SkippableTheory ]
353+ [ InlineData ( InsertStrategy . InsertReturn ) ]
354+ [ InlineData ( InsertStrategy . InsertReturnAsync ) ]
355+ public async Task InsertEntities_WithComplexType_UpdateAll ( InsertStrategy strategy )
356+ {
357+ Skip . If ( _context . IsProvider ( ProviderType . MySql ) ) ;
358+ // Oracle MERGE does not support returning entities
359+ Skip . If ( _context . IsProvider ( ProviderType . Oracle ) ) ;
360+
361+ // Arrange
362+ var entities = new List < TestEntityWithComplexType >
363+ {
364+ new TestEntityWithComplexType
365+ {
366+ TestRun = _run ,
367+ OwnedComplexType = new OwnedObject { Code = 1 , Name = "Name1" }
368+ } ,
369+ new TestEntityWithComplexType
370+ {
371+ TestRun = _run ,
372+ OwnedComplexType = new OwnedObject { Code = 2 , Name = "Name2" }
373+ }
374+ } ;
375+
376+ // Act - First insert (without CopyGeneratedColumns - returns generated IDs via RETURNING)
377+ var insertedEntities = await _context . InsertWithStrategyAsync ( strategy , entities ) ;
378+
379+ // Update the complex properties
380+ foreach ( var entity in insertedEntities )
381+ {
382+ entity . OwnedComplexType = new OwnedObject
383+ {
384+ Code = entity . OwnedComplexType . Code + 100 ,
385+ Name = $ "Updated_{ entity . OwnedComplexType . Name } "
386+ } ;
387+ }
388+
389+ // Act - Second insert with update on conflict
390+ // Using 'inserted' parameter to update all columns (both behave the same for ParameterExpression case)
391+ var updatedEntities = await _context . InsertWithStrategyAsync ( strategy , insertedEntities , o => o . CopyGeneratedColumns = true ,
392+ onConflict : new OnConflictOptions < TestEntityWithComplexType >
393+ {
394+ Update = ( inserted , excluded ) => inserted ,
395+ } ) ;
396+
397+ // Assert - complex properties should be updated
398+ Assert . Equal ( 2 , updatedEntities . Count ) ;
399+ Assert . All ( updatedEntities , e =>
400+ {
401+ Assert . StartsWith ( "Updated_" , e . OwnedComplexType . Name ) ;
402+ Assert . True ( e . OwnedComplexType . Code > 100 ) ;
403+ } ) ;
404+ }
405+
406+ [ SkippableTheory ]
407+ [ InlineData ( InsertStrategy . InsertReturn ) ]
408+ [ InlineData ( InsertStrategy . InsertReturnAsync ) ]
409+ public async Task InsertEntities_WithComplexType_UpdateWithWhere ( InsertStrategy strategy )
410+ {
411+ Skip . If ( _context . IsProvider ( ProviderType . MySql ) ) ;
412+ // Oracle MERGE does not support returning entities
413+ Skip . If ( _context . IsProvider ( ProviderType . Oracle ) ) ;
414+
415+ // Arrange
416+ var entities = new List < TestEntityWithComplexType >
417+ {
418+ new TestEntityWithComplexType
419+ {
420+ TestRun = _run ,
421+ OwnedComplexType = new OwnedObject { Code = 10 , Name = "Original1" }
422+ } ,
423+ new TestEntityWithComplexType
424+ {
425+ TestRun = _run ,
426+ OwnedComplexType = new OwnedObject { Code = 20 , Name = "Original2" }
427+ }
428+ } ;
429+
430+ // Act - First insert (without CopyGeneratedColumns - returns generated IDs via RETURNING)
431+ var insertedEntities = await _context . InsertWithStrategyAsync ( strategy , entities ) ;
432+
433+ // Update the complex property name
434+ foreach ( var entity in insertedEntities )
435+ {
436+ entity . OwnedComplexType . Name = $ "Changed_{ entity . OwnedComplexType . Name } ";
437+ entity . OwnedComplexType . Code = entity . OwnedComplexType . Code + 100 ;
438+ }
439+
440+ // Act - Second insert updating complex properties with a WHERE condition
441+ // This tests that complex property access works correctly in the Where clause
442+ var updatedEntities = await _context . InsertWithStrategyAsync ( strategy , insertedEntities , o => o . CopyGeneratedColumns = true ,
443+ onConflict : new OnConflictOptions < TestEntityWithComplexType >
444+ {
445+ Update = ( inserted , excluded ) => inserted ,
446+ Where = ( inserted , excluded ) => excluded . OwnedComplexType . Code > inserted . OwnedComplexType . Code
447+ } ) ;
448+
449+ // Assert - entities should be updated because excluded.Code (110, 120) > inserted.Code (10, 20)
450+ Assert . Equal ( 2 , updatedEntities . Count ) ;
451+ Assert . All ( updatedEntities , e =>
452+ {
453+ Assert . StartsWith ( "Changed_" , e . OwnedComplexType . Name ) ;
454+ Assert . True ( e . OwnedComplexType . Code > 100 ) ;
455+ } ) ;
456+ }
351457}
0 commit comments