我已经尝试了我能想到的一切,而我只是被卡住了。我有一个User
有Invitations
但当我尝试通过调用Invitation
向invitations
的{{1}}字段添加User
时由于AddInvitation()
而引发NotSupported
异常。我觉得这是映射覆盖中的一些东西,但我有各种其他类/关系遵循相同的模式和(到目前为止)我没有在其他地方得到这个问题。为什么后备字段是只读的,我应该怎么做以防止后备字段变为只读?
User.cs
Collection is read-only
Invitation.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;
}
}
Database.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;
}
}
Manager.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
}
我收到了实际的异常消息(最初应该添加了这个消息)
在System.ThrowHelper.ThrowNotSupportedException(ExceptionResource资源) at System.Collections.ObjectModel.ReadOnlyCollection'1.System.Collections.Generic.ICollection.Add(T value) at NHibernate.Collection.Generic.PersistentGenericBag'1.System.Collections.Generic.ICollection.Add(T item)
似乎即使我正在修改字段邀请,访问者Invitations添加的ReadOnlyCollection包装器也在修改字段本身。
答案 0 :(得分:1)
我认为问题来自ReadOnlyCollection,你有没有理由将Invitations初始化为只读集合?
在您的映射中,您正在将数据填充到邀请只读集合中,并且您可能会初始化邀请字段,因为列表是通过只读集合隐藏的。
也许每次想要访问时都尝试不重新初始化邀请集,但只返回邀请字段,您可以将此字段设为只读。
答案 1 :(得分:0)
老问题,实际问题!并且在将集合保持为只读的情况下修复并不困难:
userMapping.HasMany<Invitation>(userType => userType.Invitations)
.Not.LazyLoad()
.Inverse()
.Access.CamelCaseField() // this does the trick!
.Cascade.SaveUpdate()
.KeyColumn("User_id");
如果NHibernate通过支持字段访问集合,它不知道它是只读的,所以它将实例化一个读写集合。公共接口保持只读状态。