简体   繁体   English

EF Core 3.1删除具有子关系的父实体+保存更改+在新父中重用相同的子ID =并发异常

[英]EF Core 3.1 Removing parent entity with child relations + save changes + reuse same child id in new parent = concurrent exception

Situation before doing anything:做任何事情之前的情况:

class Parent: { int ParentId, Child Children: [] }
class Child: { int ChildId, int ParentId }
db.Parents: [{ ParentId: 1, Children:[ ChildId: 10, ParentId: 1] })
db.Children: [{ ChildId: 10, ParentId: 1 })

I'm trying to do something like:我正在尝试做类似的事情:

...
using var db = new DB();
var entity = await db.Parents.FirstOrDefaultAsync(e => e.ParentId == 1);
db.WorkdayResults.Remove(entity);
await db.SaveChangesAsync(); // After saving: db.Parents and db.Children will be empty
var entry = await db.Parents.AddAsync(new Parent{});
// entry.Entity.Children.Add(new Child {}); // This works
entry.Entity.Children.Add(new Child { ChildId: 1 }); // This does not work
await db.SaveChangesAsync() // Getting concurrent exception here
...

I don't want to change the logic, such: saving parent first, create new context and save then child with its old ChildId.我不想更改逻辑,例如:首先保存父级,创建新上下文,然后使用旧的 ChildId 保存子级。 So do you guys have any good solution for this?那么你们有什么好的解决方案吗? Is this EF Core or Devart MySql feature?这是 EF Core 还是 Devart MySql 功能?

You have an error.你有一个错误。 You need ParentId key to add a child.您需要 ParentId 键来添加孩子。 And since you db is empty now try to use this:既然你的数据库是空的,现在尝试使用这个:

[]Child children= { new Child {ParentId=1, ChildrenId=10}}
db.Parents.Add(new Parent { ParentId=1 , Chilren=  children}; 

Or if your dbcontext is configured right way you can try inverse:或者,如果您的 dbcontext 配置正确,您可以尝试逆向:

db.Children.Add( new Child { ChidrentId=10, Parent= new Parent {ParentId=1}}

But if your Ids are auto-seeds and your dbcontext is configured the right way it would be enough:但是,如果您的 Id 是自动种子并且您的 dbcontext 配置正确,那就足够了:


db.Parents.Add(new Parent { Children= { new Child {}} }; 

Only if you have a parent object already, you can use like this:只有当你已经有一个父 object 时,你才能像这样使用:

db.Children.Add( new Child {ParentId=...,ChildId=...})

Like the topic says that it was concurrent exception, so I debugged and found that for some reason EF core did set the entity state as 'Modified' if I was using old ChildId, even if the old entity didn't exists on the context anymore.就像主题说它是并发异常一样,所以我调试并发现如果我使用旧的 ChildId,EF 核心出于某种原因确实将实体 state 设置为“已修改”,即使旧实体不再存在于上下文中. So here's the very simply solution:所以这是一个非常简单的解决方案:

db.Entry(childEntity).State = EntityState.Added;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM