Repository navigation
OriginalValue access on ComplexCollections not working for Entites in Added State #38486
Copy link
Copy link
Closed
Copy link
Milestone
Description
Bug description
The new ComplexCollection in EfCore 10 does not support gettings its original Value when the entity is in the "Added" State.
The code at
efcore/src/EFCore/ChangeTracking/Internal/InternalEntryBase.InternalComplexCollectionEntry.cs
Line 243 in 2e6136a
| if (_containingEntry.EntityState == EntityState.Added) |
shows that this decision seems to be intentional.
The result is that now OriginalValues.ToObject() is now broken for all entites that contain a complexCollection, making it not viable for our application as we rely on this feature for automated mechanisms through eg the library EntityFrameworkCore.Triggered
I let AI generate a sample code (and tested it myself) that demonstrates the problem and which can be found below
Your code
using Microsoft.EntityFrameworkCore;
// -------------------------------------------------------------------
// EF Core 10 – Bug repro: ComplexCollection does not support OriginalValues
// when the entity is in the 'Added' state, causing OriginalValues.ToObject()
// to throw InvalidOperationException.
// -------------------------------------------------------------------
using var db = new OrderContext();
db.Database.EnsureCreated();
var order = new Order
{
Id = 1,
Name = "Demo Order",
LineItems =
[
new LineItem { Product = "Widget", Quantity = 2 },
new LineItem { Product = "Gadget", Quantity = 5 },
]
};
db.Orders.Add(order);
var entry = db.Entry(order);
Console.WriteLine($"Entity state : {entry.State}"); // Added
// CurrentValues works fine.
Console.WriteLine($"CurrentValues[\"Name\"] : {entry.CurrentValues["Name"]}");
// OriginalValues on a plain scalar property also works for Added (EF copies it from current).
Console.WriteLine($"OriginalValues[\"Name\"] : {entry.OriginalValues["Name"]}");
// OriginalValues.ToObject() fails when a ComplexCollection is present on an Added entity.
// EF Core has no original-value snapshot for complex-collection elements yet, so it throws:
// "The complex entry at the original ordinal '0' for the collection 'Order.LineItems'
// cannot be accessed as the containing entry is in the added state."
Console.WriteLine();
Console.WriteLine("Calling entry.OriginalValues.ToObject() ...");
try
{
var original = entry.OriginalValues.ToObject(); // <-- throws!
Console.WriteLine($"Original object: {original}");
}
catch (InvalidOperationException ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"[InvalidOperationException] {ex.Message}");
Console.ResetColor();
}
Console.WriteLine("\nDone.");
// ── Model ──────────────────────────────────────────────────────────
public class Order
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public List<LineItem> LineItems { get; set; } = [];
}
public class LineItem
{
public string Product { get; set; } = string.Empty;
public int Quantity { get; set; }
}
// ── DbContext ──────────────────────────────────────────────────────
public class OrderContext : DbContext
{
public DbSet<Order> Orders => Set<Order>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=demo.db");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// ComplexCollection requires ToJson() for relational providers.
modelBuilder.Entity<Order>()
.ComplexCollection(o => o.LineItems, b => b.ToJson());
}
}Stack traces
Unhandled exception. System.InvalidOperationException: The complex entry at the original ordinal '0' for the collection 'Order.LineItems' cannot be accessed as the containing entry is in the added state.
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntryBase.InternalComplexCollectionEntry.GetEntry(Int32 ordinal, Boolean original)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntryBase.GetComplexCollectionOriginalEntry(IComplexProperty property, Int32 ordinal)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.OriginalPropertyValues.GetValueInternal(IInternalEntry entry, IPropertyBase property)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntryPropertyValues.Clone()
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntryPropertyValues.ToObject()
at Program.<Main>$(String[] args) in C:\projects\Playground10\Playground10\Program.cs:line 40
Verbose output
EF Core version
10.0.9
Database provider
Microsoft.EntityFrameworkCore.Sqlite
Target framework
.Net 10
Operating system
No response
IDE
No response
Reactions are currently unavailable
Activity
Fix OriginalValues.ToObject for added complex collections (#38493)