NHibernate不支持树型对象
本文关键字:对象 树型 不支持 NHibernate | 更新日期: 2023-09-27 18:17:41
我有一个映射Tag
对象树的类:
public class Tag
{
public int Id { get; set; }
public int Description { get; set; }
private IList<Tag> childTag = new List<Tag>();
public virtual IEnumerable<Tag> ChildTag
{ get { return childTag.ToArray(); } }
public virtual void Add(Tag child)
{ childTag .Add(child); }
public virtual bool Remove(Tag child)
{ return childTag .Remove(child); }
}
与此地图:
public TagMap()
{
Id(x => x.Id)
.Column("Kint_T01_IdTag")
.GeneratedBy.Assigned();
HasMany(x => x.ChildTag)
.KeyColumn("ParentId")
.Cascade.All()
.Access.CamelCaseField().ReadOnly();
}
当我运行这个测试
Tag Tag= fixture.Build<Tag>().Do(x => x.Add(fixture.Create<Tag>())).Create();
Tag TagActual;
using (IUnitOfWork uow = new UnitOfWork())
{
uow.openConnection();
uow.BeginTran();
uow.TagRepository.Create(Tag);
uow.commit();
Tag.Rmove(Tag.ChildTag.First());
uow.TagRepository.Update(Tag);
uow.commit();
uow.closeConnection();
uow.openConnection();
TagActual = uow.TagRepository.GetById(Tag.Id);
TagActual.ShouldBeEquivalentTo(Tag);
uow.closeConnection();
}
失败是因为TagActual。ChildTag包含一个子元素,即使我将它从父集合中移除。
我看到在 之后uow.TagRepository.Create(Tag);
uow.commit();
表中有两个记录,并且正确设置了子表的parent
属性
Tag.Rmove(Tag.ChildTag.First());
工作正常,之后集合为空
但在
之后uow.TagRepository.Update(Tag);
uow.commit();
表中没有任何变化,'父'字段仍然设置。
这样测试就失败了,因为TagActual有一组子元素,而this应该是空的
为什么NHibernate可以正确管理add
而不能管理remove
有没有办法做到这一点,而不添加Parent
属性到我的对象和手动管理它?
我找到了
我犯了两个错误:
-
.ReadOnly();
在地图,它是无用的 - 在测试用例中忘记了beginTrans
test必须这样写
Tag Tag= fixture.Build<Tag>().Do(x => x.Add(fixture.Create<Tag>())).Create();
Tag TagActual;
using (IUnitOfWork uow = new UnitOfWork())
{
uow.openConnection();
uow.BeginTran();
uow.TagRepository.Create(Tag);
uow.commit();
uow.BeginTran();
Tag.Rmove(Tag.ChildTag.First());
uow.TagRepository.Update(Tag);
uow.commit();
uow.closeConnection();
uow.openConnection();
TagActual = uow.TagRepository.GetById(Tag.Id);
TagActual.ShouldBeEquivalentTo(Tag);
uow.closeConnection();
}
这就是NHibernate的设计方式,根据http://nhibernate.info/doc/nh/en/index.html#example-parentchild
基本上,解决方案是在添加一个额外的属性"Parent",它负责关系:
public class Tag
{
public int Id { get; set; }
public int Description { get; private set; }
private IList<Tag> childTag = new List<Tag>();
private Tag parentTag;
public virtual IEnumerable<Tag> ChildTag { get { return childTag.ToArray(); } }
public virtual void Add(Tag child) { childTag .Add(child); }
public virtual bool Remove(Tag child) { return childTag .Remove(child); }
}
与此地图:
public TagMap()
{
Id(x => x.Id)
.Column("Kint_T01_IdTag")
.GeneratedBy.Assigned();
Reference(x => x.ParentTag).Access.CamelCaseField();
HasMany(x => x.ChildTag)
.Inverse()
.KeyColumn("ParentId")
.Cascade.AllDeleteOrphan()
.Access.CamelCaseField().ReadOnly();
}