当我尝试删除具有多对一复合键的对象时,NHibernate会抛出异常。保存对象正常工作。这是一个例外:
[KeyNotFoundException: The given key was not present in the dictionary.]
System.ThrowHelper.ThrowKeyNotFoundException() +28
System.Collections.Generic.Dictionary`2.get_Item(TKey key) +7455516
NHibernate.Engine.StatefulPersistenceContext.RemoveEntity(EntityKey key) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\StatefulPersistenceContext.cs:434
NHibernate.Action.EntityDeleteAction.Execute() in d:\CSharp\NH\nhibernate\src\NHibernate\Action\EntityDeleteAction.cs:87
NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:136
NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:126
NHibernate.Engine.ActionQueue.ExecuteActions() in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:174
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:241
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:19
NHibernate.Impl.SessionImpl.Flush() in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:1479
以下是我的域名:
public class Order : EntityBase {
protected Order() {}
public Order(Guid persistenceId) : base(persistenceId) {
this.Lines = new List<OrderLine>();
}
public virtual int OrderId {get; private set;}
IList<OrderLine> Lines {get; private set;}
}
public class OrderLine : EntityBase {
protected OrderLine() {}
public OrderLine(Guid persistenceId, Order order, int lineId) : base(persistenceId) {
this.Order = order;
this.LineId = lineId;
}
public virtual Order {get; private set;}
public virtual LineId {get; private set;}
}
public abstart class EntityBase {
protected EntityBase() {}
protected EntityBase(Guid persistenceId) {
this.PersistenceId = persistenceId;
}
public virtual Guid Persistenceid {get; private set;}
public bool IsTransient {get {return Equals(this.PersistenceId, default(Guid)); }}
public override bool Equals(object obj) {
if(ReferenceEquals(null, obj))
return false;
if(ReferenceEquals(this, obj))
return true;
if(this.GetType() != obj.GetType())
return false;
return this.Equals((IEntity)obj);
}
public virtual bool Equals(IEntity other) {
if(ReferenceEquals(null, other))
return false;
if(ReferenceEquals(this, other))
return true;
if(this.IsTransient || other.IsTransient)
return false;
return this.PersistenceId.Equals(other.PersistenceId);
}
public override int GetHashCode() {
return this.IsTransient ? base.GetHashCode() : this.PersistenceId.GetHashCode();
}
}
这是我的映射文件的样子:
public class OrderClassMap : ClassMap<Order> {
public OrderClassMap() {
this.Table("Orders");
this.Id(x => x.OrderId).Generated.Identity();
this.Map(x => x.PersistenceId);
this.HasMany(x => x.Lines).Inverse().KeyColumn("OrderId").Cascade.AllDeleteOrphan();
}
}
public class OrderLineClassMap : ClassMap<OrderLine> {
public OrderLineClassMap() {
this.Table("OrderLines");
this.CompositeId()
.KeyReference(x => x.Order, "OrderId")
.KeyProperty(x => x.LineId);
this.Map(x => x.PersistenceId);
}
}
答案 0 :(得分:5)
我弄清楚导致错误的原因。我的实体都有一个PersistenceId属性,它是唯一标识每个实体的GUID。在我的基类EntityBase中,我重写了GetHashCode方法并返回基于PersistenceId的哈希码。这对NHibernate来说是错误的,因为我没有提供基于Id NHibernate预期(OrderId)的哈希码。我为所有实体实现了一个新的GetHashCode和Equals方法,删除工作正常。