我有两个实体,EntityA和EntityB。 EntityB可以可选与EntityA相关,并且具有可为空的外键列。删除EntityA时,我希望EntityB中的外键设置为null。
因此,当我删除EntityA时,我希望它在发出DELETE命令之前在任何引用的EntityB中设置外键。我已经看到NHibernate在“意外”之前做了这个,现在我真的想要它做到这一点,我似乎无法做到这一点。我能做的最好的事情就是删除EntityB,一旦它成为孤儿,这不是我想要的。当然,我可以在SQL Server中设置外键约束来将列设置为null,但我觉得NHibernate应该能够做到这一点。类似地,我可以循环遍历EntityA引用的所有EntityB以将其删除,并将它们设置为null。再说一遍,我为什么要这样做?
以下是我的实体和映射:
public class EntityA : Entity // Entity contains the ID property and implements GetHashCode() and Equals()
{
// irrelevant properties
public virtual IList<EntityB> EntityBs { get; protected set; }
}
public class EntityB : Entity
{
// irrelevant properties
public virtual EntityA EntityA { get; set; }
}
public class EntityAMap: ClassMap<EntityA>
{
public EntityAMap()
{
HasMany(c => c.EntityBs)
.ForeignKeyConstraintName("FK_EntityA_EntityB")
.KeyColumn("EntityA_Id")
.Inverse()
.Cascade.None(); // i've tried other cascade settings with little luck
}
}
public class EntityBMap: ClassMap<EntityB>
{
public EntityBMap()
{
References(c => c.EntityA)
.Nullable()
.Column("EntityA_Id")
.ForeignKey("FK_EntityA_EntityB")
.Index("IX_EntityB_EntityA_Id")
.Cascade.None();
}
}
然后我删除这样:
var entityA = Repository.Get(idToDelete);
// entityA.EntityBs.Clear(); // tried this, no affect
Repository.Remove(entityA);
Repository.Flush(); // is it possible this isn't working because I'm missing a Tx?
结果是外键约束违规,因为EntityB.EntityA_Id没有被删除。
答案 0 :(得分:1)
您需要执行以下操作:
entityA.EntityBs.ToList().ForEach(b => b.EntityA = null );
Repository.Remove(entityA);
Repository.Flush();
如果任何B仍在引用A,则无法删除A,尤其是没有级联时。
答案 1 :(得分:0)
您必须将所有级联设置为none,然后在EntityBMap中设置.inverse()。如果有效,请给我反馈。
马里乌什