nhibernate “cascade=”all-delete-orphan”错误
我的数据库中有3个表:
- Projects (id, name)
- Tags (id, name)
- ProjectsTagss (id, projectId, tagid)
As你可以看到 ProjectsTags 表是一个桥接表,
这是我流畅的 nhibernate 映射
ProjectMap.cs:
Map(x => x.Name).Not.Nullable();
HasMany(x => x.ProjectsTags).AsBag().Inverse()
.Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
ProjectsTagsMap.cs:
References(x => x.Project).Not.Nullable();
References(x => x.Tag).Not.Nullable();
TagMap.cs:
Map(x => x.Name).Not.Nullable();
如您所见,我过去没有将标签表链接到其他任何内容。我现在需要生成一个报告来显示标签以及该标签的使用频率,因此我需要从标签加入到 ProjectsTag。我尝试将这一行添加到标签映射中:
HasMany(x => x.ProjectsTags).AsBag().Inverse()
.Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
但是当我去更新标签对象上的名称并提交时,我收到此错误:
带有cascade =“all-delete-orphan”的集合不再被引用拥有实体实例
任何人都可以看到我添加的内容有任何问题,当我只是更新标签表时会导致此 nhibernate 异常。我的目标再次是能够执行以下操作:
Tag.ProjectTags.Count();
这是根据要求提供的一些附加代码:
我的标签类:
public class Tag
{
public virtual IList<ProjectTag> ProjectTags { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
i have 3 tables in my database:
- Projects (id, name)
- Tags (id, name)
- ProjectsTagss (id, projectId, tagid)
As you can see the ProjectsTags table is a bridge table
here is my fluent nhibernate mapping
ProjectMap.cs:
Map(x => x.Name).Not.Nullable();
HasMany(x => x.ProjectsTags).AsBag().Inverse()
.Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
ProjectsTagsMap.cs:
References(x => x.Project).Not.Nullable();
References(x => x.Tag).Not.Nullable();
TagMap.cs:
Map(x => x.Name).Not.Nullable();
As you can see, i historically didn't have the Tag table linked to anything else. I now need to generate a report to show Tag and how often that tag is used so i need to join from Tag to ProjectsTag. i tried adding this line into the tagsmap:
HasMany(x => x.ProjectsTags).AsBag().Inverse()
.Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
but when i go to update the name on a tag object and commit, i get this error:
A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance
can anyone see anything wrong with what i added that would be causing this nhibernate exception when i simply update the Tag table. Again my goal is to be able to do something like:
Tag.ProjectTags.Count();
Here is some additional code as requested:
my Tag Class:
public class Tag
{
public virtual IList<ProjectTag> ProjectTags { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在代码中的某个位置,您应该取消引用项目域上的原始集合。我怀疑你的代码是这样的:
如果是这种情况,你应该这样做:
Somewhere in your code, you should have dereferenced the original collection on your Project domain. I suspect that your code goes like this:
If this is the case, you should do this instead:
虽然集合没有被修改,但 NH 仍然可以认为它被修改了。类似的情况可能是由幽灵更新引起的。来自 NHibernate 3.0 Cookbook,Jason Dentler(第 184 页):“作为自动脏检查的一部分,NHibernate 将实体的原始状态与
目前的状态。否则未更改的实体可能会被不必要地更新,因为
类型转换导致此比较失败”。
集合的幽灵更新可能是由如下代码引起的:
ProjectsTags 属性以只读包装器返回集合,因此客户端代码无法向集合添加或从集合中删除元素。
将出现错误即使标签的名称没有更改:
ProjectsTags 集合应该使用 CamelCaseField 访问策略进行映射,以避免重影更新:
无论如何...
如果 ProjectsTags 表应该只包含标签的 id 和项目的 id,那么使用 FNH 多对多双向映射会更简单:
现在模型中不需要 ProjectTag 实体 可以通过两种方式检索给定标签的使用次数:
直接方式:
tag.Projects.Count() - 但它从数据库中检索所有项目
:
While a collection is not modified, NH can still think that it is. Something like this could be caused by a ghost update. From NHibernate 3.0 Cookbook, Jason Dentler (page 184): "As part of automatic dirty checking, NHibernate compares the original state of an entity to
its current state. An otherwise unchanged entity may be updated unnecessarily because a
type conversion caused this comparison to fail".
Ghost update of collection can be caused by code that looks like this:
ProjectsTags property returns the collection in readonly wrapper, so client code cannot add or remove elements to/from the collection.
The error will appear even when name of a tag is not changed:
ProjectsTags collection should be mapped with CamelCaseField access strategy to avoid ghost updated:
Anyway...
Your association seems to be diabolically complex. If ProjectsTags table should contains only id of tag and id of project, then it would be simpler to use FNH many-to-many bidirectional mapping:
Now there is no need for ProjectTag entity in the model. The count of how many times is given tag used can be retrieved in two ways:
Direct way:
tag.Projects.Count()
- but it retrieves all projects from database.Query way: