Nhibernate 删除多对一关系中的父级导致外键冲突

发布于 2024-09-30 12:33:32 字数 808 浏览 0 评论 0原文

我有一个可以有多个人员的雇主对象:

//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 列清空?

I have a Employer object that can have multiple People:

//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();

When I try to delete an employer that is linked to a person, I get a "Foreign Key violation" error.

//example
_session.Delete(oldEmployer);

How do I get nHibernate to null the CurrentEmployerId column before the employer is deleted?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

叫嚣ゝ 2024-10-07 12:33:32

尝试先清除所有 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);

try clearing all CurrentEmployer's first then deleting the 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
    }
}

then try the following (I think the employees (person) should all get updated), I don't know if this will work off the top of my head, but it may get you started in the right direction.

oldEmployer.UnemployAll();
_session.Delete(oldEmplorer);
演出会有结束 2024-10-07 12:33:32

您是否有散布在各处的代码来删除雇主?我认为通常情况下,代码中只有一个位置可以真正删除雇主,因此实际上不需要让 nhibernate 为您完成这项工作;只需在那里发表一份更新所有引用员工的声明即可。

如果您确实有这些分散的删除,那么您可以创建一个拦截器或事件侦听器来监视对表的删除,并让拦截器/侦听器更新引用员工。

Do you have code scattered all around that deletes employers? I think normally you would have only one place in the code really that deletes employers, so there wouldn't really be a need to have nhibernate do this work for you; Just have a statement there that updates all referencing employees.

If you actually do have these deletes scattered all about, then you could create an Interceptor or Event Listener that watched for deletes to the table and have the interceptor/Listener update referencing employees.

命比纸薄 2024-10-07 12:33:32

尝试做一下这个

//employer to person mappings
HasMany(x=> x.Employees)
    .Inverse() 
    .Cascade.AllDeleteOrphan();

我没有检查,但我希望它可以帮助你。

Try to do this one

//employer to person mappings
HasMany(x=> x.Employees)
    .Inverse() 
    .Cascade.AllDeleteOrphan();

I didn't check it, but I hope it could help you.

染年凉城似染瑾 2024-10-07 12:33:32

Oracle 具有内置的级联删除功能(基于外键约束)。Sybase 没有。
根据您的数据库是否支持之前和之后触发器,您可以使用之前触发器创建功能。 Sybase 12 没有这个,它只有 after 触发器,所以在 sybase 上这是不可能的。 Sybase 15有before触发器,但我还没有尝试过,但它应该可以工作,基本上你手动编写before触发器来执行级联删除。

如果您的数据库中不存在此 before 触发器功能,则这是不可能的。在删除父表之前,您必须先以编程方式删除子表行。

就是这样。

Oracle has the cascading delete feature (based on foreign key constraints) built in. Sybase does not.
Depending on if your database supports before and after triggers you can create the functionality with before triggers. Sybase 12 doesn't have this, it only has after triggers so it's impossible on sybase. Sybase 15 has before triggers but I haven't tried it yet, but it should work, basically you write the before trigger manually to do the cascading delete.

If this before trigger functionality doesn't exist in your database, this is not possible. You would have to programmatically delete the child table rows first before deleting the parents.

That's just how it is.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文