Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shadow key property unknown when updating JSON document with a list and NoTracking behavior enabled #34616

Closed
Sticcia opened this issue Sep 5, 2024 · 1 comment
Labels
area-change-tracking closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@Sticcia
Copy link

Sticcia commented Sep 5, 2024

Issue

We enabled the NoTracking query behavior on a Entity Framework DB Context.
Our setup heavily relies on entity tracking being disabled:

optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);

We then add successfully a new row containing a column with a JSON document with a list of a complex type:

public class Customer
{
	public required Guid Id { get; init; }

	public required List<Address> Addresses { get; set; }
}

public class Address
{
	public required string Street { get; set; }
}

Using the ToJson model builder:

modelBuilder.Entity<Customer>().OwnsMany(
	order => order.Addresses, ownedNavigationBuilder =>
	{
		ownedNavigationBuilder.ToJson();
	});

We then query the previously added document, and, after updating it, we are unable to save the changes in the database because of an unknown shadow key property in the list of complex objects.

We have tried to set the state of the object and of the elements in the list to Modified but found no difference:

context.Entry(customer).State = EntityState.Modified;

Code

I created a simple project to replicate the issue:
https://github.com/Sticcia/EFCore8Test

Stack Trace

The value of shadow key property 'Address.Id' is unknown when attempting to save changes.
This is because shadow property values cannot be preserved when the entity is not being tracked.
Consider adding the property to the entity's .NET type.
See https://aka.ms/efcore-docs-owned-collections for more information.

Provider and version information

EF Core version: 8.0.6
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows 11
IDE: Visual Studio 2022 17.11.0

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Sep 11, 2024

You'd need to do something like this:

var customerEntry = context.Entry(customer);
customerEntry.State = EntityState.Detached;

var i = 1;
var collectionEntry = customerEntry.Collection(c => c.Addresses);
foreach (var address in customer.Addresses)
{
    collectionEntry.FindEntry(address)!.Property("Id").CurrentValue = i++;
}

customerEntry.State = EntityState.Modified;

The actual value for this property will not be sent to the database, it just needs to be unique within the collection.

This is one of the biggest pain points that #31252 should remove.

@AndriySvyryd AndriySvyryd closed this as not planned Won't fix, can't repro, duplicate, stale Sep 11, 2024
@AndriySvyryd AndriySvyryd added the closed-no-further-action The issue is closed and no further action is planned. label Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-change-tracking closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

4 participants