簡體   English   中英

如何使用已存在於 EF 核心中的子實體保存實體?

[英]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)

;

你有三個選項可以做到這一點

  1. 使用外鍵屬性

    using ( var db = new MyDbContext(options) ) { var person = new Person { Name = "Paul", DogId = 1 }; db.Persons.Add(person); await db.SaveChangesAsync(); }
  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(); }
  3. 創建具有顯式 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM