我有这个类映射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();
表中没有任何变化,父母&#39;提交仍然设置。
这样测试失败了,因为TagActual有一个子集合,而这应该是空的
为什么NHibernate正确管理add
操作,而不是remove
有没有办法在不向我的对象添加Parent
属性并手动管理它的情况下执行此操作?
答案 0 :(得分:0)
根据http://nhibernate.info/doc/nh/en/index.html#example-parentchild
,这就是NHibernate的设计方式基本上,解决方案是添加一个额外的属性&#34; Parent&#34;谁负责这种关系:
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();
}
现在一切都应该按预期工作了......
答案 1 :(得分:0)
我找到了它:)
我犯了2个错误:
.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();
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();
}