C# 实体框架ASP.net MVC中与多个表的可选关系

C# 实体框架ASP.net MVC中与多个表的可选关系,c#,asp.net,asp.net-mvc,entity-framework,orm,C#,Asp.net,Asp.net Mvc,Entity Framework,Orm,我正在尝试构建一个ASP.NETMVC应用程序。我很难与数据注释建立某种关系 我有三张表,加班,会计,假期。每个Overhour记录可以有1个Accounting或Vacation记录,但这是可选的。所以,它不需要有一个。这是我的Overhour型号: public class Overhour { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int OverhourId { ge

我正在尝试构建一个ASP.NETMVC应用程序。我很难与数据注释建立某种关系

我有三张表,
加班
会计
假期
。每个
Overhour
记录可以有1个
Accounting
Vacation
记录,但这是可选的。所以,它不需要有一个。这是我的
Overhour
型号:

public class Overhour
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OverhourId { get; set; }

    ....

    public int? AccountingId { get; set; }
    public virtual Accounting Accounting { get; set; }

    public int? VacationId { get; set; }
    public virtual Vacation Vacation { get; set; }
}
当我删除我的
over hour
记录(如果有)时,我想同时删除
休假
会计
记录。当我这样使用它时,级联删除被禁用

我试过这个:

public class Overhour
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OverhourId { get; set; }

    ....

    public virtual Accounting Accounting { get; set; }

    public virtual Vacation Vacation { get; set; }
}
级联删除可以工作,但实体框架会创建“Accounting\u AccountingId”之类的字段,这也是必需的。这些不应该是必需的

我最后尝试的是:

public class Overhour
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OverhourId { get; set; }

    ....

    public int AccountingId { get; set; }
    public virtual Accounting Accounting { get; set; }

    public int VacationId { get; set; }
    public virtual Vacation Vacation { get; set; }
}
但这次它给了我这样一个错误:

在表xxx上引入外键xxx约束可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束

我很困惑,我做错了什么


谢谢

删除级联不是这样工作的。如果您在一小时内删除
,则不会也不应删除任何其他内容。它的工作方向相反。如果
Accounting
是必需的依赖项,并且您删除了附加到
Overhour
Accounting
实例,那么
Overhour
也应该被删除。如果外键可为NULL,则不会发生这种情况,因为它将被设置为DELETE set NULL。但是,无论哪种方式,在一小时内删除
都不会对
会计
假期
实例产生任何影响

更新

在这个场景中,创建一对一关系(这里似乎需要)相对容易,因为关系的一方是可选的。您所需要的只是:

public class Overhour
{
    ...

    public int? AccountingId { get; set; } // optional
    public virtual Accounting Accounting { get; set; }
}

public class Accounting
{
    ...

    public int OverhourId { get; set; } // required
    public virtual Overhour Overhour { get; set; }
}
这样,删除
Overhour
也将级联并删除关联的
会计
,因为它依赖于
Overhour


事情只有在双方都需要的时候才会变得复杂。然后,您必须使用fluent config将一个设置为主体,另一个设置为从属,因为此时EF无法自行做出此决定。

实际上级联删除在我的第二个示例中起作用。我很困惑。那么,在这种情况下我该怎么办呢?我应该自己删除相关记录吗?因为当我删除超过一小时的记录时,我需要删除会计记录和假期记录。问题是你如何处理它们。默认情况下,这将创建一对多,即
Overhour
有一个
Accounting
Accounting
有多个
Overhour
。这就是为什么在这个场景中它不删除
会计
,因为它可能在这个
实例之外的一小时内仍然有有效的使用。如果你真的想把
会计
绑定到一个特定的
一小时以上的
实例,那么你的关系应该是一对一的。我太迷茫了,我想我需要多读一些关于Fluent Api的东西。谢谢你的更新。事实是,会计不需要有超过一小时的记录。所以,我想双方都是可选的。也许这就是它不起作用的原因。可能没有这样的关系类型?您可以使用一对一的关系,其中双方都是可选的。然而,同样的警告也适用于这两种情况:您必须使用fluent-config来提示EF哪个是依赖的,哪个是主体。也就是说,我不确定为什么您会期望在两个方向上都有一个删除级联。如果
会计
不依赖于特定的
工时
,则逻辑上不应仅因为
工时
被删除而将其删除。如果它没有超出其与
Overhour
关系之外的值,则应该需要
Overhour