繁体   English   中英

外键约束问题?

[英]Foreign key constraint issue?

我对我的EF代码优先数据库进行了一些更改,当我尝试对其进行更新时,现在出现以下错误:

在表“ SupportTicketMessages”上引入FOREIGN KEY约束“ FK_dbo.SupportTicketMessages_dbo.SupportTickets_Ticket_Id”可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

这是我的实体:

SupportTicket:

public class SupportTicket
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required]
        public string Title { get; set; }

        [Required]
        public string Text { get; set; }

        [Required]
        public TicketUrgency Urgency { get; set; }

        [Required]
        public TicketStatus Status { get; set; }

        [Required]
        public virtual UserProfile Owner { get; set; }

        [Required]
        public DateTime Date { get; set; }
}

SupportTicketMessage:

public class SupportTicketMessage
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required]
        public virtual UserProfile Author { get; set; }

        [Required]
        public string Text { get; set; }

        [Required]
        public DateTime Date { get; set; }

        [Required]
        public virtual SupportTicket Ticket { get; set; }

        [Required]
        public int MessageNumber { get; set; }
    }

这里有什么问题? 我看不出有什么问题。

问题是两个实体中都需要UserProfile

UserProfileSupportTicketSupportTicketMessage之间,您具有三个必需的一对多关系:

  1. 一个UserProfile许多SupportTicket
  2. 一个UserProfile许多SupportTicketMessage
  3. 一个SupportTicket许多SupportTicketMessage

(左侧是主体(具有关系的主键),右侧是从属(具有关系的外键)。)

对于所需的一对多关系,EF默认情况下会向数据库中添加级联删除,即,如果删除了上方左侧的实体,则右侧的所有从属实体都应自动删除。

如果现在要删除UserProfile ,将有两个级联的删除路径到SupportTicketMessage表,即:

  • UserProfile > SupportTicket > SupportTicketMessage (由于关系1和3)
  • UserProfile > SupportTicketMessage (由于关系2)

这是SQL Server不允许的,并且是产生异常的原因。

为了解决此问题,您必须“中断”至少一种关系的级联删除路径。 您可以通过使关系成为可选关系(即:删除导航属性中的[Required]属性之一)或通过显式禁用级联删除来实现。 我选择后一种选项,因为将关系从必需更改为可选是改变业务规则的一种。 我将禁用关系1和2的级联删除,因为也许删除UserProfile不应删除所有SupportTicketSupportTicketMessage ,而是应将票证和消息分配给某些“匿名”默认用户,所以票证历史记录不会当用户想要离开系统时不会迷路。

必须使用Fluent API禁用级联删除:

modelBuilder.Entity<SupportTicket>()
    .HasRequired(s => s.Owner)
    .WithMany()
    .WillCascadeOnDelete(false);

modelBuilder.Entity<SupportTicketMessage>()
    .HasRequired(s => s.Author)
    .WithMany()
    .WillCascadeOnDelete(false);

(如果您在UserProfile具有WithMany SupportTicketSupportTicketMessage的导航集合,则必须使用带有lambda参数的WithMany调用,例如WithMany(u => u.SupportTickets)WithMany(u => u.SupportTicketMessages) 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM