[nHibernate HasMany在同一表中导致StackOverflowException

问题描述 投票:0回答:2

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

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

数据库可以正常运行,我可以轻松地在顶层添加一个新的类别。但是,一旦我尝试在另一个类别下添加类别,就会收到以下异常:

由于StackOverflowException,进程正在终止。

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

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 StackOverflow exception
        }

非常感谢您指出我做错了什么或如何解决此问题。

提前感谢:)

c# nhibernate fluent-nhibernate stack-overflow
2个回答
1
投票

也许inverse()可以提供帮助?

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

0
投票

我发现了发生StackOverflowException的问题。在子类别>父类别>子类别>父类别中进行了递归,从而创建了一个无限循环。

我没有像@collenbrecht所说的那样使用Inverse,但是我采用了另一种方法,只是稍微改变了我的数据结构:

我只保存其ID,而不是将整个ParentCategory对象保存在Category上。然后在需要时我获取整个对象。这消除了无休止的循环并解决了我的问题。

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

 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;
        }
© www.soinside.com 2019 - 2024. All rights reserved.