[英]Entity A contains Entity B, how do I Update A without inserting B (cause it already exists) EF core
[英]How to save an entity with a child entity which already exists in EF core?
我遇到了一个我从未见过的非常奇怪的问题。 我正在使用 .net CORE 3.0 + EF。 我有两个数据库模型,它们是
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Dog Dog { get; set; }
}
和
public class Dog
{
public int Id { get; set; }
public string Name { get; set; }
}
所以,假设我的数据库中已经有一条 id=1 和 Name = "Bimbo" 的 Dog 记录。 现在,我想添加一个现有狗的人:
var p = new Person
{
Name = "Peter",
Dog = new Dog
{
Id = 1
};
};
_dbContext.Persons.Add(p);
然后我得到
当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Dogs”中插入标识列的显式值
我了解 EF 尝试将狗作为新记录插入,而我需要它将我的新 Person 记录与现有的 Dog 记录绑定。
我发现这个解决方案建议明确设置外键。 还有另一种方法吗? 还是处理这种情况的正确方法? EF Core 为标识列插入显式值
您可以将外键显式添加到人员
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int DogId {get;set;}
public Dog Dog { get; set; }
}
然后您可以将狗添加为参考而不将其加载到上下文中
var p = new Person
{
Name = "Peter",
DogId = 1
};
_dbContext.Persons.Add(p)
;
你有三个选项可以做到这一点
使用外键属性
using ( var db = new MyDbContext(options) ) { var person = new Person { Name = "Paul", DogId = 1 }; db.Persons.Add(person); await db.SaveChangesAsync(); }
从上下文加载狗实例并使用该实例
using ( var db = new MyDbContext(options) ) { var dog = db.Dogs.Find(1); var person = new Person { Name = "Paul", Dog = dog }; db.Persons.Add(person); await db.SaveChangesAsync(); }
创建具有显式 ID 的 dog 实例并将其附加到上下文
using ( var db = new MyDbContext(options) ) { var dog = new Dog { Id = 1 }; db.Attach(dog); var person = new Person { Name = "Paul", Dog = dog }; db.Persons.Add(person); await db.SaveChangesAsync(); }
请参阅.net fiddle上的工作示例
当您将 Person object 添加到上下文时,EF 将其 state 以及它引用的具有主键集的任何 object 设置为已添加(如此处所述)。 这就是为什么 EF 尝试将新的 Dog object 插入到具有新 id 的数据库中,而异常指出 Dogs 表的 id 是由数据库生成的。
要解决此问题,您可以手动将新 Dog object 的 state 设置为 Unchanged,这将阻止 EF 将新记录插入数据库。:
_dbContext.Entry(person.Dog).State = EntityState.Unchanged
更好的解决方案是将 DogId 属性添加到 Person object 并设置它,而不是创建新的 Dog 实例或从数据库加载 Dog object 并将其设置为 Person ZA8CFDE6331BD59EB2AC96F8911C4B666 中建议的 Dog 属性.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.