nHibernate HasMany 在同一 table 内导致 StackOverflowException

nHibernate HasMany within the same table causes StackOverflowException

我有一个名为类别的实体,其中包含同一实体(类别)的许多子类别:

public class Category : Entity
    {
        public virtual string Name { get; set; }
        public virtual IList<Category> SubCategories { get; set; }
        public virtual Category ParentCategory { get; set; }

        public Category()
        { }

        public Category(Category category)
        {
            SubCategories = category.SubCategories.Where(c => !c.Deleted).Select(c => new Category(c)).ToList();
        }
    }

这是我的类别映射:

public class CategoryMap : NHibernateMap<Category>
    {
        public CategoryMap()
        {
            Map(x => x.Name);
            HasMany(x => x.SubCategories).KeyColumn("ParentId").Cascade.AllDeleteOrphan().AsBag();
            References(x => x.ParentCategory, "ParentId");
        }
    }

数据库种子很好,我可以轻松地在顶层添加新类别。 但是,一旦我尝试在另一个类别下添加一个类别,就会出现以下异常:

Process is terminating due to WhosebugException.

这是我尝试创建类别时的代码:

public Category CreateCategory(CreateCategoryModel model)
        {
            var category = new Category
            {
                Name = model.Name,
            };
            if (model.ParentCategory == null) return category; // Up to here it works fine. - I save the category elsewhere.

            var parent = Get(model.ParentCategory.Id);
            category.ParentCategory = parent;
            parent.SubCategories.Add(category);
            _categoryRepository.SaveOrUpdate(parent);

            return category; // If I hit these lines of code I get the Whosebug exception
        }

如果能指出我做错了什么或如何解决问题,我们将不胜感激。

提前致谢:)

也许inverse()可以帮忙?

HasMany(x => x.SubCategories).KeyColumn("ParentId").Inverse().Cascade.AllDeleteOrphan().AsBag();

我发现了 WhosebugException 发生的问题。 subcategories > parent > subcategories > parent 中存在递归,形成无限循环。

我没有看@collenbrecht 所说的使用 Inverse 的方法,但我采用了不同的方法,稍微改变了我的数据结构:

我没有在类别上保存整个 ParentCategory 对象,而是只保存它的 ID。 我会在需要时获取整个对象。这消除了无限循环并解决了我的问题。

我的类别 class 现在看起来像这样:

 public class Category : Entity
    {
        public virtual string Name { get; set; }
                public virtual IList<Category> SubCategories { get; set; } = new List<Category>();
        public virtual long? ParentId { get; set; }

        public Category()
        { }

        public Category(Category category)
        {
            SubCategories = new List<Category>();
        }
    }

映射如下:

 public class CategoryMap : NHibernateMap<Category>
    {
        public CategoryMap()
        {
            Map(x => x.Name);
            Map(x => x.ParentId);
            HasMany(x => x.SubCategories).Cascade.AllDeleteOrphan();
        }
    }

在我的服务中,我可以执行以下操作:

public Category CreateCategory(CreateCategoryModel model)
        {
            var category = new Category
            {
                Name = model.Name,
            };
            if (model.ParentCategory == null)
            {
                category.ParentId = null;
                return category;
            }

            var parent = Get(model.ParentCategory.Id);
            parent.SubCategories.Add(category);
            _categoryRepository.SaveOrUpdate(parent);
            category.ParentId = model.ParentCategory.Id;

            return category;
        }