如何保存 EF core 中已存在的具有子实体的实体?

Sof*_* Bo 4 c# entity-framework

我遇到了一个我以前从未见过的非常奇怪的问题。我正在使用 .net CORE 3.0 + EF。我有两个数据库模型,分别是

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Dog Dog { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

public class Dog
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

所以,假设我的数据库中已经有一条狗记录,id=1,名称=“Bimbo”。现在,我想添加一个有狗的人:

var p = new Person
{
    Name = "Peter",
    Dog = new Dog
    {
        Id = 1
    };
};

_dbContext.Persons.Add(p);
Run Code Online (Sandbox Code Playgroud)

然后我得到

当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Dogs”中插入标识列的显式值

据我所知,EF 尝试插入一条狗作为新记录,而我需要它将新的 Person 记录与现有的 Dog 记录绑定。

我发现这个解决方案建议明确设置外键。还有其他方法吗?或者这是处理这种情况的正确方法吗? EF Core 为标识列插入显式值

Sir*_*ufo 7

您有三个选择来做到这一点

  1. 使用外键属性

    using ( var db = new MyDbContext(options) )
    {
        var person = new Person
        {
            Name = "Paul",
            DogId = 1
        };
    
        db.Persons.Add(person);
        await db.SaveChangesAsync();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从上下文加载狗实例并使用该实例

    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();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建具有显式 ID 的狗实例并将其附加到上下文

    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();
    }
    
    Run Code Online (Sandbox Code Playgroud)

请参阅.net fiddle上的工作示例