2012-10-02 31 views
8

Estoy tratando de implementar una función de eliminación suave en mi proyecto anulando el método y deshaciendo la eliminación de las entidades que implementan mi interfaz ISoftDelete.Supresión de eliminación de entidad con asociaciones

interface ISoftDelete 
{ 
    bool IsDeleted { get; set; } 
} 

En el método SaveChanges() Estoy llamando método de mi SoftDelete() para cada entrada que se encuentra en estado 'borrado' e implementa ISoftDelete:.

var entries = this.ChangeTracker.Entries().Where(x => (x.State == EntityState.Deleted) && x.Entity is ISoftDelete) 
        .ToList(); 
       entries.ForEach(SoftDelete); 

Mi método SoftDelete() es el siguiente:

private void SoftDelete(DbEntityEntry entry) 
{ 
    if (entry.State == EntityState.Deleted && entry.Entity is ISoftDelete) 
    { 
     entry.Reload(); 
     var entity = (ISoftDelete)entry.Entity; 
     entity.IsDeleted = true; 
     entry.State = EntityState.Modified; 
    } 
} 

Esto funcionará perfectamente hasta que me encuentre con una entidad que tiene una asociación uno a uno con otra cosa. En ese momento, se inicia una excepción con este error:

{"A relationship from the 'ChildParent' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'Parent' must also in the 'Deleted' state."}

¿Hay una manera de conseguir todas las asociaciones de esa entidad y cambiar el estado eliminado para ellos también?

Ya he intentado obtener la referencia a la entidad real asociada, pero el EntityState de la entidad se establece en Unchanged en lugar de Deleted.

+3

Creo que la asociación se marca como eliminada (las asociaciones se tratan como objetos separados en EF) pero no la entidad relacionada. Ahora cuando EF intenta eliminar la asociación, no puede porque la entidad relacionada no está marcada para eliminarse. Supongo que la clave externa no admite nulos y, por lo tanto, eliminar una entidad requiere eliminar la entidad relacionada (eliminación en cascada). Puede consultar este hilo: http://stackoverflow.com/questions/10300156/ivalidatableobject-is-useless-for-ef-navigation-properties/10304323#10304323. Puede ser útil, ya que muestra cómo llegar a los objetos relacionados. – Pawel

+0

Fue útil para obtener los objetos relacionados, gracias. Sin embargo, cuando intento cambiar el estado de una de las relaciones, aparece un extraño error que dice "No se puede cambiar el estado de una relación si uno de los extremos de la relación es KeyEntry". – Jonathan

+0

¿Ha visto [esta solución] (http://connect.microsoft.com/VisualStudio/feedback/details/513174/unable-to-refresh-some-items-in-the-objectcontext)? –

Respuesta

0

En general, primero es necesario eliminar por software los elementos secundarios en las relaciones de elementos primarios y secundarios. Comience con el padre superior y repita los pasos a través de los niños. Marque cada elemento visitado, de modo que pueda rastrear si ya se borró suavemente (en caso de referencias anteriores).

Si tiene un concepto de "objeto comercial", puede agregar Childs y Parent propiedades para facilitar la navegación. De lo contrario, tendrá que "codificar manualmente" esto en cada Padre con relaciones infantiles no triviales.

También tenga en cuenta que al utilizar una declaración LINQ no tiene control sobre el desplazamiento real.

Sé que lo anterior parece mucho trabajo, pero considere cómo se dispositivo un mecanismo en EF que automáticamente deduciría la información de relación necesaria ?! Deberías terminar haciendo cosas como esta.

Cuestiones relacionadas