1

我已经在这里尝试了我能想到的一切,但我只是卡住了。我有一个User有很多Invitations但是当我尝试通过调用将异常添加Invitationinvitations字段时抛出异常,因为. 我觉得它是映射覆盖中的东西,但我有各种其他类/关系遵循相同的模式,并且(到目前为止)我在其他地方没有遇到这个问题。为什么支持字段是只读的,我应该怎么做才能防止支持字段变为只读?UserAddInvitation()NotSupportedCollection is read-only

用户.cs

public class User
{
  private IList<Invitation> invitations = new List<Invitation>();

  public virtual IEnumerable<Invitation> Invitations
  {
    get { return new ReadOnlyCollection<Invitation>(this.invitations);
  }

  public virtual User AddInvitation(Invitation invitation)
  {
    if (!this.invitations.Contains(invitation))
    {
      this.invitations.Add(invitation); // <-- throws System.NotSupportedException: Collection is read-only.
    }

    return this;
  }
}

邀请.cs

public class Invitation
{
  private User sender = null;

  public virtual User Sender
  {
    get { return this.sender; }
  }

  public virtual Invitation From(User sender)
  {
    this.sender = sender;
    return this;
  }
}

数据库.cs

public class Database
{
  // code removed for brevity
  private static void MapAssemblies(FluentNHibernate.Cfg.MappingConfiguration config)
  {
    config.AutoMappings.Add(
      AutoMap.Assembly(Assembly.GetAssembly(typeof(User)))
      .Override<User>(userMapping =>
      {
        userMapping.HasMany<Invitation>(userType => userType.Invitations)
        .Not.LazyLoad()
        .Inverse()
        .Cascade.SaveUpdate()
        .KeyColumn("User_id");
      })
      .Override<Invitation>(invitationMapping =>
      {
        invitationMapping.References<User>(invitationType => invitationType.Sender)
        .Column("User_id");
      });
    );
  }
  // code removed for brevity
}

管理器.cs

public class Manager
{
  private ISession session = null; // initialised in .ctor

  // code removed for brevity
  public void AddInvitation(/*parameters removed*/)
  {
    User user = this.session.Get<User>(identifier);
    Invitation invitation = new Invitation().From(user);
    user.AddInvitation(invitation);
    using (ITransaction transaction = this.session.BeginTransaction())
    {
      this.session.SaveOrUpdate(invitation);
      transaction.Commit();
    }
  }
  // code removed for brevity
}

我得到了实际的异常消息(最初应该添加这个)

在 System.ThrowHelper.ThrowNotSupportedException(ExceptionResource 资源) 在 System.Collections.ObjectModel.ReadOnlyCollection'1.System.Collections.Generic.ICollection.Add(T 值) 在 NHibernate.Collection.Generic.PersistentGenericBag'1.System.Collections.Generic .ICollection.Add(T 项)

似乎即使我正在修改字段邀请,访问者邀请添加的 ReadOnlyCollection 包装器也在修改字段本身。

4

2 回答 2

1

我认为问题出在 ReadOnlyCollection,您将 Invitations 初始化为只读集合有什么理由吗?

在您的映射中,您正在将数据填充到 Invitation 只读集合中,并且可能您将邀请字段初始化为 List 被只读集合隐藏。

每次要访问的时候可能尽量不要重新初始化邀请集合,而只是返回邀请字段,您可以将此字段设置为只读。

于 2012-10-18T13:48:40.713 回答
0

老问题,实际问题!在保持集合只读的同时修复并不难:

    userMapping.HasMany<Invitation>(userType => userType.Invitations)
    .Not.LazyLoad()
    .Inverse()
    .Access.CamelCaseField() // this does the trick!
    .Cascade.SaveUpdate()
    .KeyColumn("User_id");

如果 NHibernate 通过后台字段访问集合,它不知道它是只读的,所以它会实例化一个读写集合。公共接口保持只读状态。

于 2016-07-29T06:02:42.843 回答