Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

c# - Strongly-Typed ASP.NET MVC with Entity Framework

This code fails to actually save any 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 the object Model as a Department type EntityObject with an EntityState value of Detached.

After using the AttachTo method, its EntityState becomes Unchanged.

MSDN on Attaching Objects (Entity Framework)

Objects are attached to the object context in an Unchanged state.

Because of its Unchanged state, the method ApplyPropertyChanges does nothing.

I want it to instead have state Modified.

MSDN on EntityState Enumeration

Detached
The object exists but it is not being tracked by Object Services. An entity is in this state immediately after it has been created and before it is added to the object context. An entity is also in this state after it has been removed from the context by calling the Detach method or if it is loaded using a NoTrackingMergeOption.

Unchanged
The object has not been modified since it was loaded into the context or since the last time that the SaveChanges method was called.

Modified
The object is changed but the SaveChanges method has not been called.

I cannot explicitly set an EntityObject's EntityState property to Modified. It is read only.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to get the ObjectStateManager from your ObjectContext. With the ObjectStateManager, you can explicitly set the state for your object without needing to make 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");
}

The ObjectStateEntry also allows you to apply finer-grained state change data via the SetModifiedProperty. If you call SetModified, EF will treat the entire entity as modified, and persist every property to the data store. With SetModifiedProperty, EF can optimize the queries and only involve the properties that have actually changed. Using SetModifiedProperty is obviously more complex, as you usually need to know the original value of each property.

I hope this helps. ObjectStateManager is a powerful little tool in the EF toolbox, and can help improve EF v1.0's otherwise morbid performance and efficiency.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...