2015-12-04 32 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我知道,但你说,他说,他说,试过了,并没有工作。 –