2009-05-22 201 views
2

此代碼不能真正保存任何更改:強類型ASP.NET MVC實體框架

// 
// POST: /SomeType/Edit/5 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    db.AttachTo(Model.GetType().Name, Model); 
    db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

ASP.NET MVC創建對象模型與獨立的EntityState值一系類EntityObject 。

使用AttachTo方法後,其EntityState變爲未更改

MSDN on Attaching Objects (Entity Framework)

對象被附接到在不變狀態的對象 上下文。

由於其不變狀態,方法ApplyPropertyChanges什麼都不做。我想讓它改爲修改爲

MSDN on EntityState Enumeration

獨立
對象存在,但它沒有被對象 服務跟蹤。一個實體在創建 後立即處於此狀態 ,並且在它被添加到對象 上下文中之前。通過調用Detach 方法或使用 NoTrackingMergeOption加載,實體在 上下文中被刪除後,該實體也處於此 狀態。

不變
對象沒有被修改,因爲它是裝入 上下文或自最後一次 該SaveChanges方法被稱爲 。

改性
該目的改變,但是SaveChanges方法沒有 被調用。

我無法明確地將EntityObject的EntityState屬性設置爲修改爲。它是隻讀的。

使用EntityObjects強類型MVC控制器是不可能的嗎?

+0

http://stackoverflow.com/questions/922402/strongly-typed-asp-net-mvc-with-ado-net-entity-framework – 2009-05-28 18:13:38

回答

8

您需要從ObjectContext獲取ObjectStateManager。隨着ObjectStateManager,你可以明確設置對象的狀態,而無需撥打電話到數據庫:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    db.AttachTo(Model.GetType().Name, Model); 

    ObjectStateManager stateMgr = db.ObjectStateManager; 
    ObjectStateEntry stateEntry = stateMgr.GetObjectStateEntry(model); 
    stateEntry.SetModified(); // Make sure the entity is marked as modified 
    //db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 

    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

的ObjectStateEntry,您還可以通過SetModifiedProperty應用更細粒度的狀態變化數據。如果您調用SetModified,則EF會將整個實體視爲已修改,並將每個屬性保留到數據存儲區。通過SetModifiedProperty,EF可以優化查詢並僅涉及實際更改的屬性。使用SetModifiedProperty顯然更復雜,因爲您通常需要知道每個屬性的原始值。

我希望這會有所幫助。 ObjectStateManager是EF工具箱中的一個強大的小工具,可以幫助提高EF v1.0的病態性能和效率。

+0

SetModifiedProperty按預期工作。但是,SetModified似乎並未將整個實體視爲已修改。它並沒有「堅持每一個屬性到數據存儲」,它依然沒有。 – 2009-05-26 14:46:34

1

這工作:

// 
// POST: /SomeType/Edit/5 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    Model.EntityKey = (from SomeType s in db.SomeType 
         where s.Id == id 
         select s).FirstOrDefault().EntityKey; 
    db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

但有不查詢數據庫的方法嗎?

1

如果你添加一個行會發生什麼:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(Guid id, SomeType Model) 
{ 
    db.AttachTo(Model.GetType().Name, Model); 
    Model.SomeProperty = Model.SomeProperty; // This looks hacky... =(
    db.ApplyPropertyChanges(Model.EntityKey.EntitySetName, Model); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

該國是否改變?

+0

我試圖Model.Id =模型。但由於該特定字段受實體框架保護,導致了異常。我沒有嘗試任何其他人。 – 2009-05-22 20:19:44

+0

是的,這個ID是隻讀的。嘗試其他... =) – 2009-05-22 20:24:45

3

我發現以上都不是我的工作,但MSDN指南的例子做了哪裏,你從上下文中獲得原始項目,然後附加更新的項目。

第二個例子:

http://msdn.microsoft.com/en-us/library/bb896248.aspx#Mtps_DropDownFilterText

private static void ApplyItemUpdates(SalesOrderDetail updatedItem){ 
// Define an ObjectStateEntry and EntityKey for the current object. 
EntityKey key; 
object originalItem; 

using (AdventureWorksEntities advWorksContext = 
    new AdventureWorksEntities()) 
{ 
    try 
    { 
     // Create the detached object's entity key. 
     key = advWorksContext.CreateEntityKey("SalesOrderDetail", updatedItem); 

     // Get the original item based on the entity key from the context 
     // or from the database. 
     if (advWorksContext.TryGetObjectByKey(key, out originalItem)) 
     { 
      // Call the ApplyPropertyChanges method to apply changes 
      // from the updated item to the original version. 
      advWorksContext.ApplyPropertyChanges(
       key.EntitySetName, updatedItem); 
     } 

     advWorksContext.SaveChanges(); 
    } 
    catch (InvalidOperationException ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
} 

}

1

我有這個工作,但什麼亞姆沒能獲得在是的SalesOrderDetail 的母公司我怎樣才能得到它?

SalesOrderDetail.SalesOrderHead爲空並且entityreference爲空。 我的編輯例程只能訪問SalesOrderDetail的ID。

感謝 斯里蘭卡