使用NHibernate,我正在寻找一种在删除持久化项目时自动更新持久化集合的方法。例如:
var post = GetNewPost();
var blog = GetCurrentBlog();
blog.Posts.Add(post);
BlogRepository.Update(blog);
User.Posts.Add(post);
UserRepository.Update(user);
----
// Somewhere else
var blog = GetCurrentBlog();
var post = blog.Posts.Last();
blog.Posts.Remove(post);
NHibSession.Flush(); // Throws an ObjectDeletedException due to 'post'
// still being in the User.Posts collection
我理解在这个示例中可能存在模型和/或映射的问题,但是除了这些问题之外,我想找到一种方法来自动更新User.Posts集合,即从中删除'post'本身。 (也许不是世界上最好的例子,但假设有许多博客和许多用户,除了通过帖子之外彼此无关。了解这是一个外观。)
在这个例子中,我只使用了一个NHibernate会话。我愿意调整它,但我正在寻找一个方案,它应该对模型透明。 NHibernate事件也可以在桌面上展示,如果它可以被证明是一个好习惯。
我相信LINQ to SQL可以处理这种情况,所以我有点惊讶NHibernate不能(尽我所能的搜索能力)。是否有可用的补充框架?
以下是此示例的相关映射:
<class name="App.Core.Domain.Post, App.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Posts" xmlns="urn:nhibernate-mapping-2.2">
<id name="Id" type="Guid" column="PostId">
<generator class="assigned" />
</id>
...
<many-to-one cascade="save-update" access="field.pascalcase-underscore" name="Blog" column="BlogId" />
<many-to-one cascade="save-update" access="field.pascalcase-underscore" name="User" column="UserId" />
</class>
<class name="App.Core.Domain.Blog, App.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Blogs" xmlns="urn:nhibernate-mapping-2.2">
<id name="Id" type="Guid" column="BlogId">
<generator class="assigned" />
</id>
...
<bag name="Posts" cascade="all" inverse="true" access="field.pascalcase-underscore">
<key column="PostId" />
<one-to-many class="App.Core.Domain.Post, App.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>
</class>
<class name="App.Core.Domain.User, App.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Users" xmlns="urn:nhibernate-mapping-2.2">
<id name="Id" type="Guid" column="UserId">
<generator class="assigned" />
</id>
...
<bag name="Posts" cascade="all" inverse="true" access="field.pascalcase-underscore">
<key column="PostId" />
<one-to-many class="App.Core.Domain.Post, App.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>
</class>
答案 0 :(得分:0)
尝试删除帖子包上的cascade = all。当您刷新会话时,Post集合级联到帖子并尝试更新它。
您正在使用Blog.Posts.Add创建新帖子,但尝试使用PostsRepository.Delete(post)删除它。选择一种策略并坚持下去。
答案 1 :(得分:0)
我想更多地改进这个问题,比如我们用以下新的Model
扩展情况当我们的帖子与Blog之外的其他实体相关联时会发生什么?即使我们注意只通过Blog.Posts.Remove删除帖子,处理其他关联清理的一般策略是什么?假设我们不能将所有项目填充到一个聚合根中,如果可以的话,我们可以通过AR清除它们。所以基本上我们在聚合根之间有联系,清理它们的最佳做法是什么?在这个例子中,用户可以列出他们最喜欢的帖子,但这只是从用户到帖子的单向关联,没有关联。
我们是否需要域服务,从域中删除/删除实体(不仅仅是让它成为瞬态但是让它获得GC),这会删除所有关联吗?这将使NHibernate在持续变化时感到高兴。在这种情况下,我们不仅要从博客中删除帖子,还要从任何标记为收藏的用户中删除帖子。它应该存在域服务,应用服务吗?如果发生级联删除,我们如何利用此服务,比如我们删除一个标记为收藏的帖子的博客,我们是否应该使用NHib事件并检测帖子是否被删除以及清理关联?
我知道有些人建议在数据库中使用FK级联,但这只有在关联没有加载到会话中时才有效。如果它们已加载,则必须将其删除。我不喜欢这种方法的是它违反了在内存中拥有真实模型的想法,即使NHib和数据库不存在也会如此。想法?