NHibernate 中的自引用实体给对象引用一个未保存的瞬态实例异常
Self referencing entity in NHibernate gives object references an unsaved transient instance exception
我有一个名为 Category 的自引用实体。
一个类别可能有一个或多个子类别。类别也可能没有子项。
我已经制作了实体和映射,但我一直收到此异常。
NHibernate.TransientObjectException : object references an unsaved
transient instance - save the transient instance before flushing or
set cascade action for the property to something that would make it
autosave.
我是不是映射部分有问题?
是否可以一次保存所有父对象和子对象?
任何帮助将不胜感激。
代码如下
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.
}
}
我们需要分配引用的两边
public virtual void AddChild(Category childCategory)
{
childCategory.ParentCategory = this;
// add to collection as well
_childCategory.Add(childCategory);
}
您的错误消息给了您两个选择:
- 刷新前保存临时实例
- 将 属性 的级联操作设置为可以自动保存的内容
第一个选项很简单:只需在提交事务之前保存每个实例
using (var tx = _session.BeginTransaction())
{
foreach(var category in categories)
{
_session.SaveOrUpdate(category);
}
_catRepo.AddNewCategory(categories);
tx.Commit();
}
我有一个名为 Category 的自引用实体。 一个类别可能有一个或多个子类别。类别也可能没有子项。
我已经制作了实体和映射,但我一直收到此异常。
NHibernate.TransientObjectException : object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave.
我是不是映射部分有问题?
是否可以一次保存所有父对象和子对象?
任何帮助将不胜感激。
代码如下
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.
}
}
我们需要分配引用的两边
public virtual void AddChild(Category childCategory)
{
childCategory.ParentCategory = this;
// add to collection as well
_childCategory.Add(childCategory);
}
您的错误消息给了您两个选择:
- 刷新前保存临时实例
- 将 属性 的级联操作设置为可以自动保存的内容
第一个选项很简单:只需在提交事务之前保存每个实例
using (var tx = _session.BeginTransaction())
{
foreach(var category in categories)
{
_session.SaveOrUpdate(category);
}
_catRepo.AddNewCategory(categories);
tx.Commit();
}