[英]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
。
在UserProfile
, SupportTicket
和SupportTicketMessage
之间,您具有三个必需的一对多关系:
UserProfile
许多SupportTicket
UserProfile
许多SupportTicketMessage
SupportTicket
许多SupportTicketMessage
(左侧是主体(具有关系的主键),右侧是从属(具有关系的外键)。)
对于所需的一对多关系,EF默认情况下会向数据库中添加级联删除,即,如果删除了上方左侧的实体,则右侧的所有从属实体都应自动删除。
如果现在要删除UserProfile
,将有两个级联的删除路径到SupportTicketMessage
表,即:
UserProfile
> SupportTicket
> SupportTicketMessage
(由于关系1和3) UserProfile
> SupportTicketMessage
(由于关系2) 这是SQL Server不允许的,并且是产生异常的原因。
为了解决此问题,您必须“中断”至少一种关系的级联删除路径。 您可以通过使关系成为可选关系(即:删除导航属性中的[Required]
属性之一)或通过显式禁用级联删除来实现。 我选择后一种选项,因为将关系从必需更改为可选是改变业务规则的一种。 我将禁用关系1和2的级联删除,因为也许删除UserProfile
不应删除所有SupportTicket
和SupportTicketMessage
,而是应将票证和消息分配给某些“匿名”默认用户,所以票证历史记录不会当用户想要离开系统时不会迷路。
必须使用Fluent API禁用级联删除:
modelBuilder.Entity<SupportTicket>()
.HasRequired(s => s.Owner)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<SupportTicketMessage>()
.HasRequired(s => s.Author)
.WithMany()
.WillCascadeOnDelete(false);
(如果您在UserProfile
具有WithMany
SupportTicket
和SupportTicketMessage
的导航集合,则必须使用带有lambda参数的WithMany
调用,例如WithMany(u => u.SupportTickets)
和WithMany(u => u.SupportTicketMessages)
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.