Strongly typed ASP.NET MVC with Entity Framework

This code cannot actually save the changes:

// // 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 creates a Model object as an EntityObject unit type with an EntityState value of Individual .

After using the AttachTo method, its EntityState becomes Unchanged .

MSDN when attaching objects (Entity Framework)

Objects are bound to the object context in the Unchanged state.

Due to its state. No change. The ApplyPropertyChanges method does nothing.

I want the Change state to be instead.

MSDN in EntityState enumeration

Separately
An object exists but is not tracked by the Object Services object. The entity is in this state immediately after its creation and before it is added to the object context. The entity is also in this after it has been removed from the context, causing the method to break off or if it is loaded using NoTrackingMergeOption.

Without changes
The object has not been modified since it was loaded in context or since the last that the SaveChanges method is called.

Modified
The object was modified, but the SaveChanges method was not called.

I cannot explicitly set the EntityObject EntityState property to Modified . It is read-only.

Is it impossible to have strongly typed MVC controllers with EntityObjects?

+2
c # asp.net-mvc entity-framework
May 22 '09 at 20:04
source share
5 answers

You need to get an ObjectStateManager from an ObjectContext. Using the ObjectStateManager, you can explicitly specify the state for your object without requiring a call to the database:

 [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 also allows you to apply larger state data with SetModifiedProperty. If you call SetModified, EF will treat the entire object as modified and save each property in the data store. With SetModifiedProperty, EF can optimize queries and include only those properties that have really changed. Using SetModifiedProperty is obviously more complicated since you usually need to know the initial value of each property.

Hope this helps. ObjectStateManager is a powerful tool in the EF toolbar and can help improve EF v1.0, otherwise it will lead to reduced performance and efficiency.

+8
May 23 '09 at 18:55
source share

I found that none of the above seems to work for me, but the MSDN tutorial example did in which you get the source element from the context and then attach the updated element.

Second example:

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 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()); } } 

}

+3
Oct. 19 '09 at 12:58
source share

It works:

 // // 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"); } 

But is there a way without querying the database?

+1
May 22 '09 at 20:07
source share

What happens if you add one line:

 [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"); } 

Does the state change?

+1
May 22 '09 at 20:15
source share

It works for me, but what I canโ€™t get is the parent SalesOrderDetail object. How can I understand this?

SalesOrderDetail.SalesOrderHead is null, and the entity value is null. My editing procedure has access only to the SalesOrderDetail identifier.

Thanks Sri

+1
Oct 20 '09 at 13:41
source share



All Articles