在Entity Framework 7中,當我嘗試應用遷移時,我收到錯誤
在表'ChangeOrder'上引入FOREIGN KEY約束'FK_ChangeOrder_User_CreatedByID'可能會導致循環或多個級聯路徑。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY約束。
無法創建約束。查看以前的錯誤。
我知道在舊版本的Entity Framework中你可以通過添加來解決這個問題
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
到的DbContext但EF7 modelBuilder
似乎並不具有.Conventions
它和谷歌只返回舊的EF 4雖然EF 6的結果。
如何在Entity Framework 7中特定ON DELETE NO ACTION
約束?
編輯:奧列格提供的答案顯然是按照外鍵進行的,但我想在全局範圍內進行,因為使用一行代碼來全局聲明這一點會更容易,然後必須為每一個代碼指定代碼。我將最終擁有數百種關係。
編輯2:奧列格的代碼
public class ChangeOrder
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public Int16? ApprovedByID { get; set; }
public Byte ApprovalStatusID { get; set; }
public Int16 AssignedToID { get; set; }
public Int16 CreatedByID { get; set; }
public Byte CurrentStatusID { get; set; }
public DateTime? DateApproved { get; set; }
public DateTime? EndDate { get; set; }
public Byte ImpactID { get; set; }
public Byte PriorityID { get; set; }
public DateTime? StartDate { get; set; }
public Byte TypeID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string ReasonForChange { get; set; }
[ForeignKey("ApprovedByID")]
public User ApprovedBy { get; set; }
[ForeignKey("ApprovalStatusID")]
public ChangeApprovalStatus ApprovalStatus { get; set; }
[ForeignKey("AssignedToID")]
public User AssignedTo { get; set; }
[ForeignKey("CreatedByID")]
public User CreatedBy { get; set; }
[ForeignKey("ImpactID")]
public ChangeImpact Impact { get; set; }
[ForeignKey("PriorityID")]
public ChangePriority Priority { get; set; }
[ForeignKey("TypeID")]
public ChangeType ChangeType { get; set; }
[ForeignKey("CurrentStatusID")]
public ChangeStatus CurrentStatus { get; set; }
}
public class JobSightDBContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelbuilder)
{
base.OnModelCreating(modelbuilder);
}
DbSet<ChangeApprovalStatus> ChangeApprovalStatus { get; set; }
DbSet<ChangeImpact> ChangeImapct { get; set; }
DbSet<ChangeOrder> ChangeOrders { get; set; }
DbSet<ChangePriority> ChangePriorities { get; set; }
DbSet<ChangeStatus> ChangeStatus { get; set; }
DbSet<ChangeType> ChangeTypes { get; set; }
DbSet<User> Users { get; set; }
}
在GitHub上挖掘,並與MS的一個非常有耐心的人一起工作,目前的解決方案是將其添加到DbContext
protected override void OnModelCreating(ModelBuilder modelbuilder)
{
foreach (var relationship in modelbuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
{
relationship.DeleteBehavior = DeleteBehavior.Restrict;
}
base.OnModelCreating(modelbuilder);
}
那個工程
modelBuilder.Entity("myNamespace.Models.ChangeOrder", b =>
{
b.HasOne("myNamespace.Models.User")
.WithMany()
.HasForeignKey("CreatedByID")
.OnDelete(DeleteBehavior.Cascade);
});
將意味著使用REFERENCES [dbo].[User] ([CreatedByID]) ON DELETE CASCADE
創建FK_ChangeOrder_User_CreatedByID
REFERENCES [dbo].[User] ([CreatedByID]) ON DELETE CASCADE
。它應該存在於遷移期間創建的YourContextModelSnapshot.cs
protected override void BuildModel(ModelBuilder modelBuilder)
中。我不確定我是否完全理解您的問題,但我認為您應該將此類構造添加到XXXModelSnapshot.cs
或刪除此處已存在的不需要的構造。
更新:我看到你在模型中遇到了問題。您有以下屬性
public Int16? ApprovedByID { get; set; }
public Int16 AssignedToID { get; set; }
public Int16 CreatedByID { get; set; }
// navigation properties
[ForeignKey("ApprovedByID")]
public User ApprovedBy { get; set; }
[ForeignKey("AssignedToID")]
public User AssignedTo { get; set; }
[ForeignKey("CreatedByID")]
public User CreatedBy { get; set; }
默認情況下,遷移嘗試在所有屬性上設置DeleteBehavior.Cascade
。
您可以通過更改OnModelCreating
來覆蓋行為, DeleteBehavior.Restrict
為所有鍵設置DeleteBehavior.Restrict
行為,或者僅在一個鍵上設置DeleteBehavior.Cascade
或DeleteBehavior.SetNull
行為。例如,下面的代碼使用DeleteBehavior.Cascade
上CreatedByID
(產生ON DELETE CASCADE
上外鍵)和DeleteBehavior.Restrict
上其它外鍵(無ON DELETE
上外鍵):
public class JobSightDBContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelbuilder)
{
base.OnModelCreating(modelbuilder);
modelbuilder.Entity(typeof (ChangeOrder))
.HasOne(typeof (User), "ApprovedBy")
.WithMany()
.HasForeignKey("ApprovedByID")
.OnDelete(DeleteBehavior.Restrict); // no ON DELETE
modelbuilder.Entity(typeof (ChangeOrder))
.HasOne(typeof (User), "AssignedTo")
.WithMany()
.HasForeignKey("AssignedToID")
.OnDelete(DeleteBehavior.Restrict); // no ON DELETE
modelbuilder.Entity(typeof (ChangeOrder))
.HasOne(typeof (User), "CreatedBy")
.WithMany()
.HasForeignKey("CreatedByID")
.OnDelete(DeleteBehavior.Cascade); // set ON DELETE CASCADE
}
DbSet<ChangeApprovalStatus> ChangeApprovalStatus { get; set; }
DbSet<ChangeImpact> ChangeImapct { get; set; }
DbSet<ChangeOrder> ChangeOrders { get; set; }
DbSet<ChangePriority> ChangePriorities { get; set; }
DbSet<ChangeStatus> ChangeStatus { get; set; }
DbSet<ChangeType> ChangeTypes { get; set; }
DbSet<User> Users { get; set; }
}