2016-03-03 55 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

相關問題