2015-12-04 211 views
4

嵌套對象永遠不會更新下面的錯誤是什麼?EntityFramework嵌套對象更新

[Route("api/branches/{id}/devices")] 
public async Task<IHttpActionResult> PutDevice(int id, Device device) 
{ 
    Branch branch = await db.Branches.Include("devices").FirstAsync(b => b.id == id); 
    if (!ModelState.IsValid) 
    { 
     return BadRequest(ModelState); 
    } 
    if (branch == null) 
    { 
     return NotFound(); 
    } 

    device.branch = branch; 

    try 
    { 
     await db.SaveChangesAsync(); 
    } 

    catch (DbUpdateConcurrencyException) 
    { 
     if (!BranchExists(id)) 
     { 
      return NotFound(); 
     } 
     else 
     { 
      throw; 
     } 
    } 
    return StatusCode(HttpStatusCode.NoContent); 
} 

我只是傳遞設備對象和分支ID。我所要做的就是更新設備的分支......但是,這個值永遠不會改變。

我錯過了什麼?

Device.cs

public class Device 
{ 
    public Device() 
    { 
     date_created = DateTime.UtcNow; 
    } 

    [Key] 
    public int id { get; set; } 

    public string name { get; set; } 

    public virtual Branch branch { get; set; } 

    public int branch_id { get; set; } 
+0

是不是'Device'只是一個視圖模型在這裏?我沒有看到被跟蹤的實體在哪裏... –

+0

@RonBeyer請檢查編輯。 – user1027620

+0

我明白了,但它是如何進入控制器的呢?如果從視圖加載的視圖充當視圖模型,那麼當您使用設備中的Id加載另一個跟蹤的實體時,會發生什麼情況,分配其分支,然後保存它?我猜測傳入的實體沒有被跟蹤。 –

回答

3

您收到後值device並且不通過上下文跟蹤。因此,當您撥打db.SaveChanges時,上下文不會看到任何更改。

正如你在評論中提到,你有branch_iddevice類,你可以設置idbranch_id,你不需要執行查詢以加載所有分支。

要添加新設備:

device.branch_id = id; 
db.Devices.Add(device); 
db.SaveChanges(); 

要編輯現有設備:

device.branch_id = id; 
db.Entry(device).State = EntityState.Modified; 
db.SaveChanges(); 
+0

感謝您的回答。但'設備'最有可能總是在數據庫中,我只想更新關係..不要再添加它。 – user1027620

+0

沒有什麼區別,答案的主要部分是前兩行。我會回答更新實體的答案。 –

+0

再次感謝,還有一點需要注意的是,設備的branch_id可以是可選的。這很重要嗎?這意味着我們可以在任何時候都有一個沒有分支的設備。 – user1027620

2

你變設備未在EF背景下,所以EF犯規瞭解它,他將永遠不要更換設備。

你可以嘗試這樣的事情:

[Route("api/branches/{id}/devices")] 
public async Task<IHttpActionResult> PutDevice(int id, Device device) 
{ 
    Branch branch = await db.Branches.Include("devices").FirstAsync(b => b.id == id); 
    Device dbDevice = await db.Devices.Find(device.id); 
    if (!ModelState.IsValid) 
    { 
     return BadRequest(ModelState); 
    } 
    if (branch == null || dbDevice == null) 
    { 
     return NotFound(); 
    } 

    dbDevice.branch = branch; 

    try 
    { 
     await db.SaveChangesAsync(); 
    } 

    catch (DbUpdateConcurrencyException) 
    { 
     if (!BranchExists(id)) 
     { 
      return NotFound(); 
     } 
     else 
     { 
      throw; 
     } 
    } 
    return StatusCode(HttpStatusCode.NoContent); 
} 
+0

你不需要往返於服務器找到原來的設備,只有'db.Entry(設備).STATE = EntityState.Modified;'就足夠了。 –

+0

此外,由於'device'有一個'branch_id',我們又不需要往返於服務器找到任何分支,它足以設置'device.branch_id' –

+0

@RezaAghaei我知道,但你說,他說,他說,試過了,並沒有工作。 –