25

Me gustaría habilitar CASCADE DELETE en una tabla con código primero. Cuando se vuelve a crear el modelo desde cero, no hay un conjunto CASCADE DELETE aunque las relaciones se establezcan automáticamente. Lo extraño es que sí lo permite para algunas tablas con una relación de muchos a muchos, con lo que podrías pensar que podría tener problemas.¿Cómo se asegura primero que Cascade Delete esté habilitado en una relación de tabla en EF Code?

Configuración: Tabla A < - Tabla B.

puntos FK de la Tabla B para PK de la tabla A.

¿Por qué no funcionaría?

+1

¿Se requiere FK (no anulable)? En tal caso, las eliminaciones en cascada deberían ser generadas por 'OneToManyCascadeDeleteConvention'. –

+1

@Ladislav: ¿Es bueno eliminar la etiqueta general 'entity-framework'? Me preguntaba por qué esta pregunta desapareció de repente de las preguntas debajo de mis etiquetas favoritas. He agregado ahora 'entity-framework-4.1' y' entity-framework-4' y ... y ... y ... pero ahora se está volviendo un poco complicado comprobar todas esas etiquetas. No estoy seguro de si no sería mejor tener una jerarquía de etiquetas que se especializan gradualmente en una pregunta. Veo el riesgo de que menos lectores vean preguntas con solo etiquetas muy especializadas que no interesan al interlocutor. – Slauma

+1

@Slauma: Estoy de acuerdo, pero o insistiremos en cerrar las etiquetas EF 4 y EF 4.1 y usaremos solo la etiqueta EF (que creo que es la forma correcta) o etiquetaremos las preguntas según su contenido. Pronto abriré la pregunta sobre meta sobre este tema, porque hay más problemas con las etiquetas EF. –

Respuesta

53

Posible razón por la que no se obtiene la eliminación en cascada es que su relación es opcional. Ejemplo:

public class Category 
{ 
    public int CategoryId { get; set; } 
} 

public class Product 
{ 
    public int ProductId { get; set; } 
    public Category Category { get; set; } 
} 

En este modelo se obtendría una tabla de productos que tiene una clave externa a la tabla de categorías, pero esta clave es anulable y no hay eliminación en cascada configuración en la base de datos por defecto.

Si usted quiere tener la relación requiere entonces usted tiene dos opciones:

Anotaciones:

public class Product 
{ 
    public int ProductId { get; set; } 
    [Required] 
    public Category Category { get; set; } 
} 

API Fluido:

modelBuilder.Entity<Product>() 
      .HasRequired(p => p.Category) 
      .WithMany(); 

En ambos casos eliminación en cascada se configurará automáticamente .

Si usted quiere tener la relación opcional pero CON eliminación en cascada es necesario configurar esta manera explícita:

modelBuilder.Entity<Product>() 
      .HasOptional(p => p.Category) 
      .WithMany() 
      .WillCascadeOnDelete(true); 

Editar: En el último fragmento de código también se puede escribir simplemente .WillCascadeOnDelete(). Esta sobrecarga sin parámetros se establece de manera predeterminada en true para configurar la eliminación en cascada.

Ver más sobre esto en el documentation

+0

Esto significa que si no especifica la convención, WillCascadeOnDelete() está desactivado de forma predeterminada? – jaffa

+3

@Jon: No, CascadeOnDelete generalmente no está desactivado. La convención dice: Está activado si su propiedad de relación/navegación es "requerida" (= se prohíbe que la clave/referencia foránea sea nula). Pero está desactivado si su relación/navegación es "opcional" (= se permite que la clave/referencia foránea sea nula). Puede sobrescribir la convención en ambos casos: puede desactivar la eliminación en cascada para una propiedad de navegación requerida y puede activarla para obtener una propiedad de navegación opcional. También puede desactivar "OneToManyCascadeDeleteConvention". Luego, siempre debe especificar lo que desea en la API Fluent. – Slauma

+0

@Slauma He leído que se supone que las relaciones son necesarias si la clave externa no puede contener nulos, como en el caso del primer ejemplo. Lea "Convención de relación" aquí: http://msdn.microsoft.com/en-us/data/jj679962.aspx – ajbeaven

0
modelBuilder 
.Entity<Product>() 
.HasRequired(p => p.Category) 
.WithMany(x => x.Products) 
.WillCascadeOnDelete(true); 
Cuestiones relacionadas