我对我的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; }
}
这里有什么问题?我没有看到什么是错的。
答案 0 :(得分:2)
问题是两个实体都需要UserProfile
。
UserProfile
,SupportTicket
和SupportTicketMessage
之间有三个必需的一对多关系:
UserProfile
- 许多SupportTicket
s UserProfile
- 许多SupportTicketMessage
s SupportTicket
- 许多SupportTicketMessage
s (左侧是主体(具有关系的主键),右侧是从属(具有关系的外键)。)
对于所需的一对多关系,EF默认向数据库添加级联删除,即如果删除上方左侧的实体,则应自动删除右侧的所有依赖实体。
如果您现在要删除UserProfile
,您将有两个到SupportTicketMessage
表的级联删除路径,即:
UserProfile
- > SupportTicket
- > SupportTicketMessage
(因为关系1和3)UserProfile
- > SupportTicketMessage
(因为关系2)SQL Server中不允许这样做以及异常的原因。
为了解决问题,您必须“破坏”至少一个关系的级联删除路径。您可以通过建立关系可选(即:删除导航属性中的[Required]
属性之一)或通过显式禁用级联删除来实现。我会选择后一个选项,因为将关系从 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
中的导航集合引用SupportTicket
和SupportTicketMessage
,则必须使用WithMany
调用lambda参数,例如WithMany(u => u.SupportTickets)
}和WithMany(u => u.SupportTicketMessages)
。)