2016-03-03 62 views
0

我试图在WebAPI PUT控制器中用EF更新记录。我正在使用以下代码EF中的更新记录无法按预期方式工作

 Product dbProduct = db.Products.FirstOrDefault(s => s.InternalReferenceId == InternalReferenceId && s.SupplierId == SupplierId); 

    if (dbProduct != null) 
    { 
     db.Products.Attach(dbProduct); 
     var entry = db.Entry(dbProduct); 
     entry.Property(e => e.Description).IsModified = true; 

     await db.SaveChangesAsync(); 
    } 
    else 
    { 
     return NotFound(); 
    } 

    return Ok(); 

找到该产品,因为它返回200 Ok。但没有更新。我目前只是试图更新说明。

我打电话给api.com/api/products/update?InternalReferenceId=1&SupplierId=1,如上所述,它找到了一条记录。在PUT请求中,我有以下内容

{ 
    "description": "testing 123" 
} 

为什么不更新?

+0

您正在获取'entity'并将其作为附件添加,因为它没有指定新的“Description”值。 –

+0

那会怎样?这条线的工作原理是'dbProducts.Description = product.Description;',但是附加点是什么,获取条目和设置是否被修改? – brother

+0

你应该用'ID'和'updated values'发送一个新的'entity class'对象,然后把这个对象附加到'dbContext'上。 –

回答

1

你得到的实体和连接它,因为它是不分配描述的新的价值。与您现有的代码试试这个:

Product dbProduct = db.Products.FirstOrDefault(s => s.InternalReferenceId == InternalReferenceId && s.SupplierId == SupplierId); 

if (dbProduct != null) 
{ 
    dbProduct.Description = "testing 123"; 
    await db.SaveChangesAsync(); 
} 
else 
{ 
    return NotFound(); 
} 

return Ok(); 

但是,最好的方式去将是:

  1. IDupdated column值发送实体的更新对象bodyPUT请求。
  2. 使用[FromBody]接收对象并将其附加到您的上下文中。
  3. SaveChanges

事情是这样的:

public bool Put([FromBody]Product updatedProduct) 
{ 
    db.Products.Attach(updatedProduct); 
    var entry = db.Entry(updatedProduct); 
    entry.Property(e => e.Description).IsModified = true; 

    return db.SaveChanges() > 0; 
} 

和你的JSON看起来像:

{ 
    "ProductID": 1, //id of your record to be updated. 
    "InternalReferenceId": 1, 
    "SupplierId": 1, 
    "Description": "testing 123" 
} 

要遵循的方法需要实体的object与数据库的至少其原有ID以便您可以直接将其附加到您的dbContext。当你在实体框架的连接模式下工作,没有必要使用Attach方法,在此默认

db.Products.Attach(dbProduct); 
var entry = db.Entry(dbProduct); 
entry.Property(e => e.Description).IsModified = true; 
+0

为什么要创建一个新实体(updatedProduct)。为什么不直接使用实体“dbProduct”? – brother

+0

是的,但我不会,也不会有ProductID。在这种特殊情况下,根本不可能 – brother

+0

那么你应该使用答案中的第一个'code snippet'。 t需要再次附加'entity',只需设置更新的值并调用'SaveChanges()' –

0

试试这个代码: -

var dbProduct = db.Products.FirstOrDefault(s => s.InternalReferenceId == InternalReferenceId && s.SupplierId == SupplierId); 

     if (dbProduct != null) 
     { 
      dbProduct.Description="Bla Bla Bla "; 
      db.Products.Attach(dbProduct); 
      var entry = db.Entry(dbProduct); 
      entry.Property(e => e.Description).IsModified = true; 

      await db.SaveChangesAsync(); 
     } 
     else 
     { 
      return NotFound(); 
     } 

     return Ok(); 
+0

是的,那是有效的。但是,如果我只是添加“dbProduct.Description =”Bla Bla Bla“;”并删除“db.Products。附(数据库产品); var entry = db.Entry(dbProduct); entry.Property(e => e.Description).IsModified = true;“。那么这3条线的要点是什么?它们在干什么? – brother

0

:如果你不能在requestbody发送object,那么你不需要这些线模式当您从数据库中获取对象实体框架将存储对象的状态以及您何时调用方法SaveChanges()实体框架将比较对象的状态并应用更改。当我们在断开模式下工作时,我们使用Attach。在这种情况下,我们需要使用Attach将对象的状态赋予Entity框架。

+0

http:// www。 entityframeworktutorial.net/EntityFramework5/attach-disconnected-entity-graph.aspx – Majed

相关问题