Aquí está mi situación:
public abstract class Article { [key] public Guid Guid { get; set;} public string Name { get; set;} . . . } public class Download : Article { ... } public abstract class Category : Article { ... } public class DownloadCategory : Category { .... } Y luego debería tener una relación de muchos a muchos entre Download y DownloadCategory como esta:
public class DownloadInCategory { [Key, Column(Order = 1), Required] [ForeignKey("Download")] Public Guid DownloadGuid { get; set; } Public Download Download { get; set; } [Key, Column(Order = 2), Required] [ForeignKey("Category")] Public Guid CategoryGuid { get; set; } Public DownloadCategory Category { get; set; } } Cuando llamo a Add-Migration la migración creada para la entidad DownloadInCategory es:
CreateTable("dbo.DownloadInCategories", c => new { CategoryGuid = c.Guid(nullable: false), DownloadGuid = c.Guid(nullable: false), }) .PrimaryKey(t => new { t.CategoryGuid, t.DownloadGuid }) .ForeignKey("dbo.DownloadCategories", t => t.CategoryGuid) .ForeignKey("dbo.Downloads", t => t.DownloadGuid, cascadeDelete: true) .Index(t => t.CategoryGuid) .Index(t => t.DownloadGuid); Aquí está mi pregunta: como notará, no está agregando cascadeDelete: true a una de las claves externas. ¿¿¿¿¿¡¡¡¡¡¡POR QUÉ!!!!!!?????
Debo mencionar que no modelbuilder ninguna de las convenciones del constructor de modelos. Por lo tanto, este esquema debe agregar Casscade al eliminar en la migración. Mis propiedades son [Required] .
¿Qué estoy haciendo mal?
Gracias chicos...
Actualización: tenga en cuenta que las clases de Article y Category son abstract . Cambié de clases arriba
Actualización 2: no hay ningún problema lógico con este esquema. Si edito la migración manualmente, actualizará la base de datos normalmente.
Actualización 3: Mi metodología de herencia EF es TPC
Actualización 4: después de algunas investigaciones y pruebas, parece que el problema se hereda de Category . Cuando DownloadCategory se hereda de Category , Cascade no se implementa. pero cuando heredo DownloadCategory directamente del artículo, se implementa Cascade. Pero ¿Por qué otra vez?
Creo que esto se debe a que:
DownloadCategory : Category : Articlecontra
Download : Article La clave está en la clase Artículo. Múltiples categorías de DownloadCategories podrían usar la misma Category , por lo que no se eliminará en cascada, ya que esto podría dañar otras categorías de DownloadCategory .
Esto posiblemente sea una falla de Entity Framework, ya que está utilizando TPC, esto debe inferirse. Eche un vistazo a este artículo para encontrar soluciones.
Concretamente estas secciones:
En la mayoría de los casos, Entity Framework puede inferir qué tipo es el dependiente y cuál es el principal en una relación. Sin embargo, cuando se requieren ambos extremos de la relación o ambos lados son opcionales, Entity Framework no puede identificar al dependiente y al principal. Cuando se requieren ambos extremos de la relación, use
WithRequiredPrincipaloWithRequiredDependentdespués del métodoHasRequired. Cuando ambos extremos de la relación son opcionales, useWithOptionalPrincipaloWithOptionalDependentdespués del métodoHasOptional.
// Configure the primary key for the OfficeAssignment modelBuilder.Entity<OfficeAssignment>() .HasKey(t => t.InstructorID); modelBuilder.Entity<Instructor>() .HasRequired(t => t.OfficeAssignment) .WithRequiredPrincipal(t => t.Instructor);Puede configurar la eliminación en cascada en una relación mediante el método
WillCascadeOnDelete. Si una clave externa en la entidad dependiente no admite valores NULL, Code First establece la eliminación en cascada en la relación. Si una clave externa en la entidad dependiente es anulable, Code First no establece la eliminación en cascada en la relación, y cuando se elimina el principal, la clave externa se establecerá ennull.Puede eliminar estas convenciones de eliminación en cascada usando:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>() modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()El siguiente código configura la relación necesaria y luego deshabilita la eliminación en cascada.
modelBuilder.Entity<Course>() .HasRequired(t => t.Department) .WithMany(t => t.Courses) .HasForeignKey(d => d.DepartmentID) .WillCascadeOnDelete(false);