我的项目有一个具有属性的Ticket
实体。OwnedBy
我正在使用 nHibernate 将票证保存到数据库中。
潜在票证所有者的规范来源是 Active Directory。由于我不想每次加载票证时都查询 Active Directory,因此我还保留Ticket.OwnedBy
到数据库并在获取票证时从那里加载它。
当票证的所有者被重新分配时,我Owner
从 Active Directory 中获取新的并将其分配给Ticket.OwnedBy
,然后调用 Session.SaveOrUpdate(ticket)。当我提交事务时,NHibernate 会抛出一个,NonUniqueObjectException
因为Owner
具有相同 ID 的一个已经与会话相关联。
类定义
class Ticket {
public int Id { get; set; }
public Owner OwnedBy { get; set; }
/* other properties, etc */
}
class Owner {
public Guid Guid { get; set; }
public string Name { get; set; }
public string Email { get; set; }
/* other properties, etc */
}
流畅的 nHibernate 映射
class TicketMap : ClassMap<Ticket> {
public TicketMap() {
Id(x => x.Id);
References(x => x.OwnedBy)
.Cascade.SaveUpdate()
.Not.Nullable();
/* other properties, etc */
}
}
class OwnerMap : ClassMap<Owner> {
public OwnerMap() {
Id(x => x.Guid)
.GeneratedBy.Assigned()
Map(x => x.Name);
Map(x => x.Email);
/* other properties, etc */
}
}
示例代码
// unitOfWork.Session is an instance of NHibernate.ISession
Ticket ticket = unitOfWork.Session.Get<Ticket>(1);
Owner newOwner = activeDirectoryRepo.FindByGuid(/* guid of new owner, from user */);
ticket.OwnedBy = newOwner;
unitOfWork.Session.SaveOrUpdate(ticket);
unitOfWork.Commit(); // Throws NonUniqueObjectException
我希望 nHibernate 用未附加的属性覆盖现有Owner
的属性。(我从 AD 获取的对象中的名称或电子邮件可能不同,并且 AD 应该是规范来源。)我尝试在 SaveOrUpdate(ticket) 之前调用Session.SaveOrUpdateCopy(ticket.OwnedBy)
和Session.Merge(ticket.OwnedBy)
,但仍然抛出异常。我也读过这个相关的问题,NonUniqueObjectException
但是调用 Session.Lock() 也没有用。
我有两个问题:
- 有没有一种简单的方法可以让 nHibernate 服从我的意愿?
- 在尝试将我从 AD 获取的所有者视为与我存储在数据库中的所有者相同的类型时,我可能在架构上犯了错误。我怎样才能改进这个设计,这样我就不需要让 nHibernate 屈服于我的意愿了?