我有一个可以有多个人的雇主对象:
//entities
public class Person {
public virtual Guid Id {get;set;}
public virtual string Name {get;set;}
public virtual Employer CurrentEmployer {get;set;}
}
public class Employer {
public virtual Guid Id {get;set;}
public virtual string Name {get;set}
public virtual IList<Person> Employees {get;set;}
}
//person to employer mappings
References(x => x.CurrentEmployer)
.Cascade.All()
.Column("CurrentEmployerId")
.ForeignKey("FK_Person_CurrentEmployer");
//employer to person mappings
HasMany(x=> x.Employees)
.Inverse()
.Cascade.All();
当我尝试删除与某人关联的雇主时,我收到“外键违规”错误。
//example
_session.Delete(oldEmployer);
如何在删除雇主之前让nHibernate使CurrentEmployerId列为空?
答案 0 :(得分:1)
首先尝试清除所有CurrentEmployer,然后删除Employee
public class Employer
{
public virtual Guid Id {get;set;}
public virtual string Name {get;set}
public virtual IList<Person> Employees {get;set;}
public void UnemployAll()
{
foreach(var employee in Employees)
{
employee.CurrentEmployer = null;
}
Employees = new List<Person>(); // clear it
}
}
然后尝试以下(我认为员工(人)都应该更新),我不知道这是否会起作用,但它可能会让你开始朝着正确的方向前进。
oldEmployer.UnemployAll();
_session.Delete(oldEmplorer);
答案 1 :(得分:0)
你是否有分散的代码删除雇主?我认为通常你会在代码中只有一个地方真的删除了雇主,所以没有必要让nhibernate为你做这项工作;只需在那里更新所有引用员工的声明。
如果您确实将这些删除分散在一起,那么您可以创建一个Interceptor或Event Listener来监视表的删除并让拦截器/侦听器更新引用员工。
答案 2 :(得分:0)
尝试这样做
//employer to person mappings
HasMany(x=> x.Employees)
.Inverse()
.Cascade.AllDeleteOrphan();
我没有检查,但我希望它可以帮到你。
答案 3 :(得分:0)
Oracle内置了级联删除功能(基于外键约束).Sybase没有。 根据您的数据库是否支持触发器之前和之后,您可以使用before触发器创建功能。 Sybase 12没有这个,它只有after触发器,因此在sybase上是不可能的。 Sybase 15之前有触发器,但我还没有尝试过,但它应该可以工作,基本上你手动编写before触发器来进行级联删除。
如果数据库中不存在此触发前功能,则无法进行此操作。在删除父项之前,您必须先以编程方式删除子表行。
就是这样。