¿Por qué al configurar la eliminación en cascada entre la entidad principal y la secundaria no se crea la cascada en la migración?
Ejemplo habitual de blog/publicación:
class Blog { public int Id { get;set; } public IList<Post> Posts { get;set;} } class Post { public int Id { get;set; } public Blog Blog { get;set;} }
En el archivo EntityTypeConfiguration
public override void Configure(EntityTypeBuilder<Notification> builder) { builder.HasMany(n => n.Posts).WithOne(e => e.Blog) .OnDelete(DeleteBehavior.Cascade); }
¿Por qué crea el script de migración de?
... migrationBuilder.AddForeignKey( name: "FK_Posts_Blogs_BlogId", table: "Posts", column: "BlogId", principalTable: "Blogs", principalColumn: "Id", onDelete: ReferentialAction.Restrict); ...
Nota la
onDelete: ReferencialAcción.Restringir
Entiendo que EF realmente hará la eliminación en cascada internamente siempre que incluya los objetos secundarios para que funcione, pero ¿por qué no aprovechar la eliminación en cascada de los Servicios de base de datos para poder eliminarla en un comando en lugar de 1 + n comandos SQL, es decir? 1 x Registro de blog y nx publicaciones.
Imagina que hay miles de publicaciones y estás eliminando un blog.
Después de revisar el proyecto en el que estaba tratando de hacer esto, me di cuenta de que Dbcontext se heredó de una clase base que tenía este código en ...
private void ConfigureEntities(ModelBuilder modelBuilder) { modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly); var entityTypes = modelBuilder.Model .GetEntityTypes() .ToList(); // Disable cascade delete var foreignKeys = entityTypes .SelectMany(e => e.GetForeignKeys().Where(f => f.DeleteBehavior == DeleteBehavior.Cascade)); foreach (var foreignKey in foreignKeys) { foreignKey.DeleteBehavior = DeleteBehavior.Restrict; } }
Al final, copié esto en Gist Project y lo reproduje de inmediato.
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfigurationsFromAssembly(typeof(TestContext).Assembly); var entityTypes = modelBuilder.Model .GetEntityTypes() .ToList(); var foreignKeys = entityTypes .SelectMany(e => e.GetForeignKeys().Where(f => f.DeleteBehavior == DeleteBehavior.Cascade)); foreach (var foreignKey in foreignKeys) { foreignKey.DeleteBehavior = DeleteBehavior.Restrict; } }
No estoy seguro de por qué se hizo esto, pero planeo averiguarlo, creo que proviene de una plantilla anterior que estábamos usando.