NHibernate,更新会话外的只读集合(改变一个不可变集合实例)

本文关键字:集合 一个 不可变 实例 改变 只读 NHibernate 更新 会话 | 更新日期: 2023-09-27 18:17:42

我正试图通过NHibernate测试一个简单的对象编辑,我得到了一些奇怪的结果。

我有这个类映射标记对象作为一个树:

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

做一个简单的测试:

        using (IUnitOfWork uow = new UnitOfWork())
        {
            uow.Start();
            uow.TagRepository.Create(Tag);
            uow.Commit();
            uow.End();
            // Act
            Tag.remove(Tag.Children.First());
            uow.Start();
            uow.TagRepository.Update(Tag);
            uow.Commit();
            uow.End();
            uow.Start();
            TagActual = uow.TagRepository.GetById(Tag.Id);
            //Assert
            TagActual.ShouldBeEquivalentTo(Tag);
            uow.End();
        }

我得到这个错误:

NHibernate.HibernateException : changed an immutable collection instance: [Gedi.Domain.Object.Entity.Tag.Children#21]

当我在单个会话中运行测试时(在操作之间没有关闭会话),一切都很顺利,没有引发异常(除了NHibernate没有像我在这里报告的那样更新表)

需要一些指导,以及解决这个问题的步骤。

谢谢。

编辑

这是工作方式

        using (IUnitOfWork uow = new UnitOfWork())
        {
            uow.Start();
            uow.TagRepository.Create(Tag);
            uow.Commit();
            Tag.Remove(Tag.Children.First());
            uow.TagRepository.Update(Tag);
            uow.Commit();
            uow.End();
            uow.Start();
            TagActual = uow.TagRepository.GetById(Tag.Id);
            TagActual.ShouldBeEquivalentTo(Tag);
            uow.End();
        }

但是我认为在商业代码中,我可能需要在会话之外工作,所以我想让它在任何情况下都运行。

我编辑了一些方法名,因为我没有在数据访问层之外暴露会话和会话的概念,因为会话是特定于NHibernate的

编辑2:

this too works fine:

using (IUnitOfWork uow = new UnitOfWork())
        {
            uow.Start();
            uow.TagRepository.Create(Tag);
            uow.Commit();
            uow.End();
            // Act
            Tag.Description = "EDITED";
            uow.Start();
            uow.TagRepository.Update(Tag);
            uow.Commit();
            uow.End();
            uow.Start();
            TagActual = uow.TagRepository.GetById(Tag.Id);
            //Assert
            TagActual.ShouldBeEquivalentTo(Tag);
            uow.End();
        }

NHibernate,更新会话外的只读集合(改变一个不可变集合实例)

我看到一些选项

  • 使用单个会话并检查是否有方法执行会话flush以将更改持久化到数据库。

  • 使用单个会话但添加事务,然后在Act之前提交以持久化您的更改。

  • 使用merge将元素附加到不同的会话session.Merge(Tag)

  • 在每次打开新会话时从数据库中获取元素,而不是使用相同的实例