ASP.NET MVC 2:使用 EntitySet 更新 Linq-To-Sql 实体
我有一个 Linq to Sql 实体,它有一个 EntitySet。在我的视图中,我显示实体及其属性以及子实体的可编辑列表。用户可以动态添加和删除这些子实体。到目前为止,DefaultModelBinder 工作正常,它正确绑定了子实体。
现在我的问题是我无法让 Linq To Sql 删除已删除的子实体,它会很乐意添加新实体但不会删除已删除的子实体。我已在外键关系中启用级联删除,并且 Linq To Sql 设计器向外键关系添加了“DeleteOnNull=true”属性。如果我像这样手动删除子实体:
myObject.Childs.Remove(child);
context.SubmitChanges();
这将从数据库中删除子记录。 但我无法让它适用于模型绑定对象。我尝试了以下操作:
// 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");
}
这会引发 InvalidOperationException,我有一个德国操作系统,所以我不确定错误消息的英文是什么,但它说了一些类似于实体需要版本(时间戳行?)或者没有更新检查策略。我已将 UpdateCheck="Never" 设置为除主键列之外的每一列。
public ActionResult Update(MyObject obj)
{
_repository.MyObjectTable.Attach(obj, true);
_repository.SubmitChanges(); // never gets here, exception at attach
}
我读过很多有关 Linq To Sql 的类似“问题”,但似乎大多数“问题”实际上是设计使然。那么我的假设是否正确,即这并不像我期望的那样有效?我真的需要手动迭代子实体并手动删除、更新和插入它们吗?对于这样一个简单的对象,这可能可行,但我计划使用嵌套的 EntitySet 等创建更复杂的对象。这只是一个测试,看看什么有效,什么无效。到目前为止,我对 Linq To Sql 感到失望(也许我只是不明白)。对于这种情况,实体框架或 NHibernate 是更好的选择吗?或者我会遇到同样的问题吗?
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 Framework or NHibernate a better choice for this scenario? Or would I run into the same problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它肯定可以在 .NET 4 附带的实体框架中工作(我在 RC 版本中做了类似的事情)
这并不能解释异常但是:
您应该处置
ObjectContext (很可能)包含在您的存储库中。上下文缓存项目,并且应该仅用于单个工作单元。
尝试使用如下模式:
在获取项目时,也创建一个新的存储库。它们的创建和处置成本都很低,因此应尽快处置。
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:
When fetching items, create a new repository as well. They are cheap to create and dispose, and should be disposed as quickly as possible.