2012-04-12 10 views
13

Utilizando el enfoque del primer código de Entity Framework.¿Qué camino tomar para que las eliminaciones en cascada entren en una relación de uno a varios?

Supongamos que tengo dos clases de entidades:

[Table("Objects")] 
public class DbObject : IValidatableObject 
{ 
    public long Id { get; set; } 

    public string Name { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<DbObjectProperty> Properties { get; set; } 
} 

[Table("ObjectProperties")] 
public class DbObjectProperty 
{ 
    public long Id { get; set; } 

    public string Name { get; set; } 
    public string Value { get; set; } 

    [Display(Name = "Object"), UIHint("Object")] 
    public long ObjectId { get; set; } 
    public virtual DbObject Object { get; set; } 
} 

Puntos a tener en cuenta aquí:

  • DbObject sólo tiene una propiedad de navegación, pero ninguna columna con una clave externa
  • DbObjectProperty tiene una navegación propiedad y una columna correspondiente con una clave externa
  • I Debería ser obvio que si elimino un objeto, quiero que sus propiedades vayan con él, pero si elimino una sola propiedad, no quiero que desaparezca todo el objeto.

En el método OnModelCreating para el contexto DB, hasta ahora tenía lo siguiente para definir la relación:

modelBuilder.Entity<DbObjectProperty>() 
    .HasRequired(op => op.Object) 
    .WithMany(obj => obj.Properties) 
    .HasForeignKey(op => op.ObjectId) 
    .WillCascadeOnDelete(false); 

Por supuesto, esto significa que no se producirán eliminaciones en cascada. Mi pregunta es: si cambio esto a true, ¿eso hace lo que quiero? Recuerde que si elimino un objeto, quiero que sus propiedades vayan con él, pero si borro una sola propiedad, no quiero que desaparezca todo el objeto.

El código de migración generada automáticamente para este cambio (de false a true) es la siguiente:

DropForeignKey("ObjectProperties", "ObjectId", "Objects"); 
DropIndex("ObjectProperties", new[] { "ObjectId" }); 
AddForeignKey("ObjectProperties", "ObjectId", "Objects", "Id", cascadeDelete: true); 
CreateIndex("ObjectProperties", "ObjectId"); 

Me preocupa que esto parece dar a entender que la supresión de una propiedad eliminará el objeto asociado. ¿Lo hará?

Respuesta

13

La dirección de Cascading La eliminación de una relación en la base de datos se define por cuál es el principal (tabla de la clave primaria/única) y cuál es el dependiente (tabla de la clave externa) de esta relación.

Luego, si elimina el principal, también se eliminan todos los dependientes que tienen un valor de clave externa correspondiente al valor clave primario/único de ese principal. No hay eliminación en cascada en la dirección de dependiente al principal.

En su caso, el principal es DbObject y el dependiente es DbObjectProperty porque es la entidad/tabla con la clave externa.

raramente No tendría sentido tener una eliminación en cascada al revés - especialmente en x-a-muchas relaciones: Si elimina un dependiente (DbObjectProperty) y el director (DbObject) se borran automáticamente, una clave externa la restricción se violaría si hay otro dependiente que se refiere al principal que se va a eliminar.

No necesita preocuparse.

+0

[¡Gracias!] (Http://meta.stackexchange.com/questions/700/) – Timwi

+0

La regla de oro es, con la eliminación en cascada, si al eliminar un registro se rompe la clave externa de otro registro, ese registro dependiente se elimina también. – orad

+0

Así 'modelBuilder.Entity () .HasMany (p => p.Children) .WithOne (c => c.Parent)' es lo mismo que 'modelBuilder.Entity () .HasOne (c => c.Parent) .WithMany (p => p.Children) '(especifican la misma relación)? –

Cuestiones relacionadas