Specifying ON DELETE NO ACTION in Entity Framework 7?
The construction
modelBuilder.Entity("myNamespace.Models.ChangeOrder", b =>
{
b.HasOne("myNamespace.Models.User")
.WithMany()
.HasForeignKey("CreatedByID")
.OnDelete(DeleteBehavior.Cascade);
});
will means creating FK_ChangeOrder_User_CreatedByID
with REFERENCES [dbo].[User] ([CreatedByID]) ON DELETE CASCADE
. It should exist in protected override void BuildModel(ModelBuilder modelBuilder)
of YourContextModelSnapshot.cs
created during migration. I'm not sure that I full understand your question, but I think that you should either add such construct to XXXModelSnapshot.cs
or to remove unneeded construct, which already exist here.
UPDATED: I see that you have the problem in the Model. You have the following properties in
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; }
By default migration try to set DeleteBehavior.Cascade
on all the properties.
You can overwrite the behavior by changing OnModelCreating
, which sets either DeleteBehavior.Restrict
behavior for all the keys or to set on one only key the DeleteBehavior.Cascade
or DeleteBehavior.SetNull
behavior. For example, the below code uses DeleteBehavior.Cascade
on CreatedByID
(which creates ON DELETE CASCADE
on the foreign keys) and DeleteBehavior.Restrict
on other foreign keys (no ON DELETE
on the foreign keys):
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; }
}
After digging around on GitHub, and working with a very patient guy from MS there, the current solution is to add this to the 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);
}