在同一上下文中添加父实体和子实体,并调用SaveChanges
我有一个查找项和一个父实体,我想在同一个事务中将它们一起添加。
举例来说,我使用以下代码:
foreach (ParentDto parentdto in ParentList)
{
Parent newParent = new Parent();
if (parentdto.itemid == 0)
{
var currentItem = await (from k in _context.LookupItems where k.Keyword.ToLower() == keyword.KeywordData.ToLower() select k).FirstOrDefaultAsync();
if (currentItem == null)
{
LookupItem item = new TLookupItem();
item.name = parentdto.itemName;
newParent.Item = item;
}
}
newParent.Id = Guid.CreateVersion7();
newParent.Name = parentdto.Name;
_context.Parents.Add(newParent);
}
await _context.SaveChangesAsync();
然而这会产生一个异常:
插入语句与外键约束冲突 "FK_Parents_LookupItems"。冲突发生在数据库 "ProjectDb",表 "dbo.LookupItems",列 'Id'。该语句已终止。
我该怎么办?
注:LookupItems 表具有主键列 Id。Parents 表有一个 LookupItemId 列,它是外键,引用 LookupItems 表的 Id 列。
解决方案
我在这里做出了一些假设——它们确实覆盖了大量场景,可能也包括你们的情况。如果这些假设是错误的,你需要根据你的具体设置进行调整。
- 你在
Parent类中有一个导航属性,用于保存子对象 - 数据库使用SQL Server
- 在你的表中使用
IDENTITY主键
在这种情况下:通过以下代码向数据库添加新条目
var entry = _context.LookupItems.Add(item);
并不会创建一个新的 Id 值——你并没有真正把记录添加到数据库中,只是添加到了你的上下文(内存中)。
处理方式是:
- 创建新的父对象
- 创建新的子对象,并把它分配给一个导航属性
- 一次性保存完整的对象图,让EF Core处理在将行插入数据库表时修正
Id值所需的所有细节。
试试这段代码:
// Create new parent object - as is
Parent newParent = new Parent();
newParent.Name = "myName";
// Create new child object
LookupItem item = new LookupItem();
item.data= "test";
// Assign new child object to parent
newParent.lookup = item;
// Now save complete object graph to context
_context.Parents.Add(newParent);
// Persist changes made to database
await _context.SaveChangesAsync();
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。