#nhibernate #orm #fluent-nhibernate #mapping #fluent-nhibernate-mapping
#nhibernate #orm #свободно-nhibernate #сопоставление #fluent-nhibernate-mapping
Вопрос:
У меня есть объект, ссылающийся на себя, с именем Category. Категория может иметь одну или несколько дочерних категорий. Категория также может не иметь дочерних элементов.
Я создал объект и сопоставление, но продолжаю получать это исключение.
NHibernate.Исключение TransientObjectException: объект ссылается на несохраненный временный экземпляр — сохраните временный экземпляр перед сбросом или установите каскадное действие для свойства на что-то, что сделало бы его автосохраненным.
Я делаю что-то не так с частью сопоставления?
Возможно ли сохранить все родительские и дочерние объекты одновременно?
Любая помощь была бы оценена.
Ниже приведен код
POCO
public class Category
{
private ICollection<Topic> _topics;
private ICollection<Category> _childCategory;
private ICollection<Media> _media;
private Category _parentCategory;
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual bool IsActive { get; set; }
public virtual Category ParentCategory
{
get { return _parentCategory ?? (_parentCategory = new Category()); }
protected set { _parentCategory = value; }
}
public virtual ICollection<Category> ChildCategory
{
get { return _childCategory ?? (_childCategory = new List<Category>()); }
protected set { _childCategory = value; }
}
public virtual void AddChild(Category childCategory)
{
childCategory.ParentCategory = this;
}
}
Сопоставление
public class CategoryMapping : IAutoMappingOverride<Category>
{
public void Override(AutoMapping<Category> mapping)
{
mapping.Map(c => c.Name).Length(30);
mapping.Map(c => c.Description).Length(160);
mapping.References(x => x.ParentCategory)
.Cascade.None()
.Column("ParentCategoryId");
mapping.HasMany(x => x.ChildCategory)
.Inverse().Cascade.All()
.KeyColumn("ParentCategoryId");
}
}
Тест
Я создаю родительскую и дочернюю категории и пытаюсь сохранить их все сразу.
public void CanSaveAllNewObjectGraphFromCategory() {
#region Categories and Child
var categories = new sq.Category()
{
Description = "Category1",
IsActive = true,
Name = "Categoy1"
};
var childCat = new List<sq.Category>() {
new sq.Category(){
Description = "ChildCategory1",
IsActive = true,
Name = "CCategoy1"
},
new sq.Category(){
Description = "ChildCategory2",
IsActive = true,
Name = "CCategoy2"
}
};
foreach (var item in childCat)
{
categories.AddChild(item);
}
#endregion
using (var tx = _session.BeginTransaction())
{
_catRepo.AddNewCategory(categories);
tx.Commit(); // Error occurs when commit is executed.
}
}
Ответ №1:
В вашем сообщении об ошибке было предложено два варианта:
- Сохраните временный экземпляр перед сбросом
- Установите каскадное действие для свойства на что-то, что сделало бы его автосохраненным
Первый вариант прост: просто сохраните каждый экземпляр перед фиксацией транзакции
using (var tx = _session.BeginTransaction())
{
foreach(var category in categories)
{
_session.SaveOrUpdate(category);
}
_catRepo.AddNewCategory(categories);
tx.Commit();
}
Ответ №2:
Нам нужно было бы назначить обе стороны ссылок
public virtual void AddChild(Category childCategory)
{
childCategory.ParentCategory = this;
// add to collection as well
_childCategory.Add(childCategory);
}
Комментарии:
1. Я все еще получаю то же исключение после назначения другой стороны ссылки.