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().

我有一些东西

  • 项目对象-这表示一个基本项目

  • ProjectDependency对象-这是将一个项目映射到另一个项目(依赖项目)的映射对象。请参见nhibernate关系:

  • 以下是ProjectDependencies映射类:

      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);
    
        }
    }