-
Notifications
You must be signed in to change notification settings - Fork 3.2k
JSON: InvalidOperationException by deleting entity with owned entities #34566
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
Comments
@goodstas Sorry for being so slow responding here.
This is a reasonable solution. Owned types are not a great fit for this, and JSON mapping from complex types should not have this issue. But for now, state of the owned types also needs to be changed to match that of the owner. |
@ajcvickers So if you say that "Owned types are not a great fit for this" then what i should use? |
@ajcvickers , @roji : if there is noithing what fits good, may be you can suggest what to change to achieve the same result? |
File a bug
I have Person entity which contains some complex property Details which contains list of complex property SubDetail .
I want to store property Details into the jsonb type column of table Person.
I read that the it's still NOT possible to save complex property to Json column so i used OwnsOne and OwnsMany methods to map everything in my db context.
In addition i want to implement Soft Delete mechanism for the Person entity. The Person entity includes IsDeleted property and also implements interface ISoftDeleteEntity.
I also defined index for the Person with constraint of "IsDeleted = False". Because i'm interested to index only "alive" entities.
The db context definition for Person looks as follows :
I overrides SaveChange method of DB Context to manipulate with the Person entity when the delete request is coming before actually implementing changes on DB.
What i do :
I change the state of the entity.entry to Modified.
I give 'True' value to IsDeleted property and call base.SaveChanges() .
After that i got an exception that the stack of it i included below.
I look for more information about this kind of exception and i found this link
I can not understand what i do in the code that makes efcore thinks that i try to change the owner of an owned entity.
The exception is about Subdetail.Id where Subdetail is owned by Details and Details is owned by Person.
I uploaded small project to reproduce the bug . Here is a link.
You will find the sln file inside WebApplication1 folder.
The scenario for reproducing after you configured appsettings with Postgres details , applied migration and ran the application.
{"Id":"f97271fb-96c3-403f-ba62-14f6d5c76bdb","Name":"aaa","PersonalDetails":{"BoolDetail":true,"StrDetail":"asdasdada","SubDetails":[{"IntSubDetail":1,"StrSubDetail":"a","DoubleSubDetail":1},{"IntSubDetail":2,"StrSubDetail":"b","DoubleSubDetail":2},{"IntSubDetail":3,"StrSubDetail":"c","DoubleSubDetail":3}]},"IsDeleted":null,"DeletionTime":null}
Include stack traces
###My Debug
I called ChangeTracker.ToDebugString() method and this is what i got after changing the state of the Person entry to Modified :
Details {PersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166} Deleted
PersonId: 'aab817dd-262e-46cd-a3a5-9c39dbf6b166' PK FK
BoolDetail: 'True'
StrDetail: 'asdasdada'
SubDetails: [{DetailsPersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166, Id: 1}, {DetailsPersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166, Id: 2}, {DetailsPersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166, Id: 3}]
Person {Id: aab817dd-262e-46cd-a3a5-9c39dbf6b166} Modified
Id: 'aab817dd-262e-46cd-a3a5-9c39dbf6b166' PK
DeletionTime: '29/08/2024 15:16:10' Modified Originally
IsDeleted: 'True' Modified Originally
Name: 'aaa' Modified
PersonalDetails: {PersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166}
SubDetail {DetailsPersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166, Id: 1} Deleted
DetailsPersonId: 'aab817dd-262e-46cd-a3a5-9c39dbf6b166' PK FK
Id: 1 PK
DoubleSubDetail: 1
IntSubDetail: 1
StrSubDetail: 'a'
SubDetail {DetailsPersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166, Id: 2} Deleted
DetailsPersonId: 'aab817dd-262e-46cd-a3a5-9c39dbf6b166' PK FK
Id: 2 PK
DoubleSubDetail: 2
IntSubDetail: 2
StrSubDetail: 'b'
SubDetail {DetailsPersonId: aab817dd-262e-46cd-a3a5-9c39dbf6b166, Id: 3} Deleted
DetailsPersonId: 'aab817dd-262e-46cd-a3a5-9c39dbf6b166' PK FK
Id: 3 PK
DoubleSubDetail: 3
IntSubDetail: 3
StrSubDetail: 'c'
So i guess that the issue is that Subdetail and Details entries states remained in Deleted State?
But actually i don't need that ChangeTracker will track these objects in such way. They are going to be stored as json.
I found a solution. I don't know if it's a good one or walk-around.
I defined some interface IDetachEntity and just change the state of all of these entities from Deleted to Detached.
Now Details and Subdetail class inherit from this interface and i do the following in my code :
` var detachDeleteEntities = this.ChangeTracker
.Entries()
.Where(e => e.State == Microsoft.EntityFrameworkCore.EntityState.Deleted);
foreach (var entity in detachDeleteEntities)
{
entity.State = Microsoft.EntityFrameworkCore.EntityState.Detached;
}
`
After that i don't get an exception.. and things work as expected.
Include provider and version information
EF Core version: 8.0.8
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 8.0.4
Target framework: NET 8.0
Operating system: Windows 11
IDE: ( Visual Studio 2022 17.9.4)
@roji , i will appreciate your comment for this issue.
The text was updated successfully, but these errors were encountered: