Fix: Nullable owned entity data preservation when moving between parents#36768
Fix: Nullable owned entity data preservation when moving between parents#36768Copilot wants to merge 4 commits intorelease/10.0from
Conversation
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
|
@AndriySvyryd - closing this draft PR for now. This will need to retargeted from main when ready |
AndriySvyryd
left a comment
There was a problem hiding this comment.
@copilot Rebase on main. Add a test based on the repro:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
await using var context = new TestDbContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
// Test that demonstrates the issue
var parent1 = new Parent();
var parent2 = new Parent();
var entity = new EntityWithOwnedData
{
Data = new OwnedData { Value = "Test Value" }
};
parent1.Entities.Add(entity);
context.Parents.AddRange(parent1, parent2);
context.SaveChanges();
Console.WriteLine(entity.Data is null); // ✅ False - data exists
// Move entity to new parent
parent1.Entities.Remove(entity);
parent2.Entities.Add(entity);
context.SaveChanges();
Console.WriteLine(entity.Data is null); // ❌ True - data is null
public class Parent
{
public int Id { get; set; }
public List<EntityWithOwnedData> Entities { get; set; } = new List<EntityWithOwnedData>();
}
public class EntityWithOwnedData
{
public Parent Parent { get; set; }
public int Id { get; set; }
public OwnedData? Data { get; set; }
}
public class OwnedData
{
public string Value { get; set; }
}
public class TestDbContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<EntityWithOwnedData> Entities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<EntityWithOwnedData>()
.OwnsOne(e => e.Data);
}
}
Done. Rebased on main and added the test in commit 366537d9. The test demonstrates the issue where nullable owned entity data should be preserved when moving entities between parent collections. |
|
@copilot Create a new PR targeting main |
I've created a new branch
The branch is ready locally but I cannot push it to create a PR since I don't have direct push access to new branches. The branch exists locally at commit d31b2738b2 based on main (84b8d15). |
…ctions Apply changes from PR #36768 to main branch: - ChangeDetector.ThrowIfKeyChanged: Allow FK changes for owned entities in collection navigations - NavigationFixer.UndeleteDependent: Set state to Added when FK overlaps PK in owned collection - InternalEntryBase.SetPropertyModified: Allow key modification for owned collection entities - Add test: Nullable_owned_entity_data_is_preserved_when_moving_between_parents - Update existing tests that previously expected InvalidOperationException Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
|
Superseded by #37693 |
This PR fixes issue #36206 where nullable owned entity data is lost when moving entities between parent collections in EF Core.
Problem
When moving an owned entity from one parent's collection to another parent's collection, the owned entity's data becomes null after
SaveChanges(). This occurs because:Solution
The fix involves two key changes to the change tracking infrastructure:
ChangeDetector.cs
Allows key property changes for owned entities in collection navigations when they are part of an ownership foreign key. This is necessary because moving an owned entity between parent collections legitimately requires changing the foreign key values.
NavigationFixer.cs
When an owned entity in a collection navigation is moved between parents and its foreign key properties are part of the primary key, treat it as a new entity (Added state) rather than a Modified entity. This ensures the owned data is preserved correctly.
Testing
Added a comprehensive SQL Server functional test (
Nullable_owned_entity_data_preserved_when_moving_between_parents) that validates:The test reproduces the exact scenario from the issue and validates that the fix resolves the problem.
Example Scenario
Branch Information
This PR is created from branch
copilot/fix-36206-maintargetingmain.💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.