Is it possible to get cascade delete on this object model?
public class Entity
{
[Key, Column("Id"), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
}
public class Comment : Entity
{
public string Text { get; set; }
}
public class Owner : Entity
{
public Owner()
{
Pets = new List<Pet>();
Comments = new List<Comment>();
}
public string Name { get; set; }
public virtual ICollection<Pet> Pets { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Pet : Entity
{
public Pet()
{
Comments = new List<Comment>();
}
public virtual Owner Owner { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public string Name { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Pet>()
.HasOptional(d => d.Owner)
.WithMany(d => d.Pets)
.WillCascadeOnDelete(true);
}
This model will generate a database that will cascade delete Pets when a Owner gets deleted. But it will not cascade delete Comment, it will just delete the FK from the Comments table. If I try to modify the constraints accordingly.
ALTER TABLE [dbo].[Comments] WITH CHECK ADD CONSTRAINT [FK_Comments_Pets_Pet_Id] FOREIGN KEY([Pet_Id])
REFERENCES [dbo].[Pets] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Comments] CHECK CONSTRAINT [FK_Comments_Pets_Pet_Id]
GO
ALTER TABLE [dbo].[Comments] WITH CHECK ADD CONSTRAINT [FK_Comments_Owners_Owner_Id] FOREIGN KEY([Owner_Id])
REFERENCES [dbo].[Owners] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Comments] CHECK CONSTRAINT [FK_Comments_Owners_Owner_Id]
GO
The following sql error appears.
Introducing FOREIGN KEY constraint 'FK_Comments_Pets_Pet_Id' on table 'Comments' may cause cycles or multiple cascade paths
This brings me to the conclusion that the model created cannot support cascade delete and I’m am forced to to the delete of comments separatly. Or am I’m missing something here?
Yes the model doesn’t support direct cascade delete in SQL server because even if you don’t think about it your database representation support same
Commentrow to be associated with bothOwnerandPet. If you then deleteOwnerit will trigger cascade delete toCommentand pet andPetwill trigger cascade delete toCommentas well => multiple cascade paths which are not supported in SQL server.This is usually handled by manual deletion or by separate database trigger handling deletion of related records.