C# 为什么nhibernate抱怨删除此对象?
我有一些东西C# 为什么nhibernate抱怨删除此对象?,c#,nhibernate,fluent-nhibernate-mapping,C#,Nhibernate,Fluent Nhibernate Mapping,我有一些东西 项目对象-这表示一个基本项目 ProjectDependency对象-这是将一个项目映射到另一个项目(依赖项目)的映射对象。请参见nhibernate关系: 以下是ProjectDependencies映射类: public class ProjectDependencyMap { public ProjectDependencyMap() { References(x => x.Project).Not.Nullable().
public class ProjectDependencyMap
{
public ProjectDependencyMap()
{
References(x => x.Project).Not.Nullable().Fetch.Join();
References(x =>.DependencyProject).Not.Nullable().Column("DependencyProjectId").Fetch.Join();
}
}
这是项目地图文件:
public class ProjectMap
{
public ProjectMap()
{
HasMany(x => x.ProjectDependencies).AsBag().Inverse().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
HasMany(x => x.ProjectDependentOf).KeyColumn("DependentProjectId").AsBag().Inverse().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
}
}
通常这很好,但有时当我使用以下命令删除项目时:
var project = Model.GetProject(id);
Repository.Delete(project);
Repository.Commit()
我得到这个错误:
删除的对象将通过级联重新保存(从关联中删除删除的对象)[ProjectDependency\324]
有人能帮我澄清问题所在吗?如果我使用上述映射的方式不正确就本回答而言,我假设
Project.ProjectDependencies
是ProjectDependency.Project
关系的另一面,而不是ProjectDependency.Dependency
关系。(现在说快3倍)
考虑以下对象:
var projectA = new Project();
var projectB = new Project();
var dep1 = new ProjectDependency
{
Project = projectA,
Dependent = projectB
};
projectA.ProjectDependencies.Add(dep1);
。。。并将它们全部保存到数据库中。现在,让我们删除一个
session.Delete(projectA);
一切正常。NHibernate在ProjectDependencies
集合中级联删除,因此projectA
和dep1
都被删除<代码>项目B留在数据库中
好的,让我们重新设置。让我们从数据库中的projectA
、projectB
和dep1
重新开始。此外,让我们添加以下内容:
var projectC = new Project();
var dep2 = new ProjectDependency
{
Project = projectC,
Dependent = projectA
};
projectC.ProjectDependencies.Add(dep2);
现在删除projectA
会发生什么
session.Delete(projectA);
一切都像以前一样进行着<代码>dep1将被级联删除。但是,没有任何东西需要清理,因此出现了错误dep2
仍然有一个对projectA
的引用,我们正在尝试删除该引用
错误消息建议的解决方案是在尝试删除实体之前清理这些关系。但是,你打算怎么做呢?从projectA
开始,我们如何找到dep2
和projectC
来清理它们
两种选择:
- 执行查询:
,然后手动清理关系session.query()。其中(x=>x.Dependent==projectA)
- 将另一个集合添加到
:项目中
。。。然后NHibernate会为您处理清理工作。我假设关系是多对多的,ProjectDependency是一个表示联接表的实体,很难从您的问题中分辨出来。我假设: 项目(项目D) 带有外键的ProjectDependency(ProjectId,DependentProjectId)返回到项目 要删除项目记录,必须删除引用它的任何项目依赖项记录。这意味着删除ProjectDependency.ProjectId引用项目的ProjectDependency记录和ProjectDependency.DependentProjectId引用的项目Dependency记录。要在代码中执行此操作,只需从集合中删除引用的实体。因为您使用的是存储库模式,所以应该在Delete方法中实现此操作
public void Delete(Project project)
{
using (var txn = _session.BeginTransaction())
{
project.ProjectDependencies.Clear();
project.DependentDependentOf.Clear();
_session.Delete(project);
txn.Commit();
}
}
在下面的两个方法调用中显示一些代码会有所帮助:
Repository.Delete(project);
Repository.Commit();
但这是我的2美分
从ProjectDependencies
映射中删除.Inverse()
。
如果希望nhibernate在“一对多”关系中从“一”端管理状态,则不应在HasMany
映射中使用.Inverse()
所以它变成这样:
public class ProjectMap
{
public ProjectMap()
{
HasMany(x => x.ProjectDependencies).AsBag().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
HasMany(x => x.ProjectDependentOf).KeyColumn("DependentProjectId").AsBag().Inverse().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
}
}
希望这有帮助。试试:引用(x=>x.Project)。Not.Nullable().Fetch.Join().LazyLoad()代码>@George=这似乎没有什么区别。实际上,我已经有了你的最后一个建议(见更新的问题),我在哪里有这个ProjectDependentOf属性。我以前没有包括它,因为我认为它不是材料,但现在我已经添加了它。请告知。另外,你能澄清你所说的“手动清理关系”是什么意思吗?另一个问题是,我没有看到任何其他项目依赖于此项目(如你的示例)因此,我不清楚是什么在试图保留评论中对我的问题的任何想法?我想nhibernate会为我这样做,因为我在问题中列出了与Cascase.DeleteOrphan的映射?
public class ProjectMap
{
public ProjectMap()
{
HasMany(x => x.ProjectDependencies).AsBag().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
HasMany(x => x.ProjectDependentOf).KeyColumn("DependentProjectId").AsBag().Inverse().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
}
}