ASP.NET MVC 2: Updating a Linq-To-Sql Entity with an EntitySet
I have a Linq to Sql Entity which has an EntitySet. In my View I display the Entity with it's properties plus an editable list for the child entites. The user can dynamically add and delete those child entities. The DefaultModelBinder works fine so far, it correctly binds the child entites.
Now my problem is that I just can't get Linq To Sql to delete the deleted child entities, it will happily add new ones but not delete the deleted ones. I have enabled cascade deleting in the foreign key relationship, and the Linq To Sql designer added the "DeleteOnNull=true" attribute to the foreign key relationships. If I manually delete a child entity like this:
myObject.Childs.Remove(child);
context.SubmitChanges();
This will delete the child record from the DB. But I can't get it to work for a model binded object. I tried the following:
// this does nothing
public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities
{
var obj2 = _repository.GetObj(id); // obj2 has 6 child entities
if(TryUpdateModel(obj2)) //it sucessfully updates obj2 and its childs
{
_repository.SubmitChanges(); // nothing happens, records stay in DB
}
else
.....
return RedirectToAction("List");
}
and this throws an InvalidOperationException, I have a german OS so I'm not exactly sure what the error message is in english, but it says something along the lines of that the entity needs a Version (Timestamp row?) or no update check policies. I have set UpdateCheck="Never" to every column except the primary key column.
public ActionResult Update(MyObject obj)
{
_repository.MyObjectTable.Attach(obj, true);
_repository.SubmitChanges(); // never gets here, exception at attach
}
I've read alot about similar "problems" with Linq To Sql, but it seems most of those "problems" are actually by design. So am I right in my assumption that this doesn't work like I expect it to work? Do I really have to manually iterate through the child entities and delete, update and insert them manually? For such a simple object this may work, but I plan to create more complex objects with nested EntitySets and so on. This is just a test to see what works and what not. So far I'm disappointed with Linq To Sql (maybe I just don't get it). Would be the Entity Framewo开发者_如何学编程rk or NHibernate a better choice for this scenario? Or would I run into the same problem?
It will definately work in Entity Framework that comes with .NET 4 (I'm doing similar things in the RC version)
This does not explain the exception but:
You should dispose the ObjectContext
that's (most likely) wrapped in your repository. The context caches items, and should only be used for a single unit-of-work.
Try to use a pattern like:
public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities
{
using(var repository = CreateRepository())
{
var obj2 = _repository.GetObj(id);
if(TryUpdateModel(obj2))
{
repository.SubmitChanges();
}
else
.....
}
return RedirectToAction("List");
}
When fetching items, create a new repository as well. They are cheap to create and dispose, and should be disposed as quickly as possible.
精彩评论