2016-06-21 127 views
0

我試圖瞭解如何更新一條記錄並首次向該記錄添加相關實體,然後使用新創建的相關外鍵更新原始記錄記錄。添加相關實體後更新實體的外鍵

例如,假設我有兩個表:一個用於人員(tbl_person),另一個用於地址(tbl_address)。

+----+------------+-----------+-----------+ 
| PK | First Name | Last Name | AddressFK | 
+----+------------+-----------+-----------+ 
| 1 | Michael | Jordan |   1 | 
| 2 | Lebron  | James  |   | 
+----+------------+-----------+-----------+ 

    public int PersonID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int? AddressID { get; set; } 
    public virtual tbl_Address tbl_Address { get; set; } 

    entityBuilder 
     .HasOne(t => t.tbl_Address) 
     .WithOne(t => t.tbl_Person) 
     .HasForeignKey<tbl_Person>(d => d.AddressID) 
     .IsRequired(false); 

+----+-------------------+----------+-------+ 
| PK | Address Line 1 | City | State | 
+----+-------------------+----------+-------+ 
| 1 | 123 Sesame Street | New York | NY | 
+----+-------------------+----------+-------+ 

    public int AddressID { get; set; } 
    public string AddressLine1 { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
    public virtual tbl_Person tbl_Person { get; set; } 

我的應用程序收到需要更新的後續JSON記錄。

{ 
    "address": { 
    "addressLine1": "789 Hollywood Ave", 
    "city": "Hollywood", 
    "state": "CA" 
    }, 
    "firstname": "Lebron", 
    "lastname": "Brown", 
    "id": 2, 
} 

我需要更新勒布朗詹姆斯是勒布朗布朗,也加上他的地址。現在我搜索記錄,並執行以下操作,它更新的人員記錄,並創建一個地址記錄:

var person = _db.tbl_Person 
    .Include(t => t.tbl_address) 
    .Where(t => t.Id == json.id).First(); 

person.firstname = json.firstname; 
person.lastname = json.lastname; 
if(person.tbl_Address == null) 
{ 
    person.tbl_Address = new tbl_Address() { 
     AddressLine1 = json.address.addressLine1, 
     City = json.address.city, 
     State = json.address.state, 
    }; 
} 

db.SaveChanges(); 

問題是,當我試圖讓對方addressID保存更改之前等於新建addressID它給我一個關於外鍵約束的錯誤。

person.AddressID = person.tbl_Address.Id; 
db.SaveChanges(); 

任何幫助,將不勝感激。謝謝

LINK TO CROSSPOST

我結束了crossposting到的EntityFramework核心Github上,因爲我開始認爲這可能是一個錯誤,因爲它不產生在子實體的外鍵自動喜歡它應該。 GitHub上的問題附有示例項目(稍微比這裏顯示的示例更復雜),如果您想要查看它,請複製錯誤:https://github.com/aspnet/EntityFramework/issues/5833

+0

具有數據註釋或EntityTypeConfigurations的類聲明將有所幫助,但基本上不會手動更新FK,因爲在SaveChanges調用之前,它們都採用默認值(default(int)== 0 '),這就是爲什麼有一個例外。 –

+0

好吧,這是我的問題更多樣本..但它是相當接近我的實際表。我按要求添加了類聲明。 – chris

+0

在你的例子中,通過設置'person.tbl_Address',EF將插入地址並自行更新'Person'。 –

回答

0

如果您的模型設置正確, t需要設置AddressID。它會自動更新。在SaveChanges()調用AddressID的值之前的時間是default(int) == 0 - 這就是發生異常的原因。這個聲明應該足夠了:

public class Person { 
    public int AddressID {get;set;} 
    [ForeignKey(nameof(Person.AddressID))] 
    public Address tbl_Address {get;set;} 
} 

TU更新地址我的代碼這種方式改變

if (json.address != null) 
{ 
    if(person.tbl_Address == null) 
    { 
     person.tbl_Address = new tbl_Address(); 
    } 
    person.tbl_Address.AddressLine1 = json.address.addressLine1, 
    person.tbl_Address.City = json.address.city, 
    person.tbl_Address.State = json.address.state 
} 

,如果人已經有一個地址,它會更新,否則會造成新的。不需要設置外鍵 - EF會爲您處理。

+0

我最初認爲我沒有必要定義addressID,直到我運行它,它創建了預期的地址,但從未將addressID添加到person表中。我的表格略有不同,我只是忽略了業務邏輯以專注於問題,但總體來說它是一樣的。我正在做一個快速愚蠢的項目來測試這些示例表,看看我是否得到相同的結果 – chris

+0

我更新了示例以根據需要執行更新/插入。 –

+0

我最終交叉發送到EntityFramework Core Github,因爲我開始認爲它可能是一個錯誤,因爲它不會自動生成子實體中的外鍵。在GitHub上的問題有示例項目攻擊與錯誤複製如果你想檢查出來:https://github.com/aspnet/EntityFramework/issues/5833 – chris

0

在EF有兩種方式設置的關係,

  • 設置FK屬性:當實體在你的數據庫已經存在使用此變種。

  • 設置導航屬性:如果是新實體,則使用此變體。當您撥打SaveChanges時,新實體將保存在您的數據庫中,並且FK列也將被設置。

所以,如果Address已經存在,你需要做的唯一的就是搜索其Id,並設置在Person實體的FK財產。

如果Address不存在,然後創建一個新的實例,並調用SaveChanges

person.tbl_Address = new tbl_Address() { 
    AddressLine1 = json.address.addressLine1, 
    City = json.address.city, 
    State = json.address.state, 
}; 
db.SaveChanges(); 

之後叫你應該能夠看到AddressId在您Person實體的值。

+0

,但在我的情況下,該人存在且地址不存在,我該怎麼辦?我需要更新人員的姓氏並導航到該地址並首次添加地址,但也要將該地址ID返回給該人員並更新該表格 – chris

+0

Hi @chris,您是否看到我答案的最後部分? – octavioccl

+0

我最終交叉發送到EntityFramework Core Github,因爲我開始認爲它可能是一個錯誤,因爲它不會自動生成子實體中的外鍵。在GitHub上的問題有示例項目攻擊與複製的錯誤,如果你想檢查它:https://github.com/aspnet/EntityFramework/issues/5833 – chris