with pattern framework example driven domain ddd business arquitectura and c# entity-framework domain-driven-design code-first

c# - pattern - Código de EF primero: ¿Cómo eliminar una fila de la Colección de una entidad mientras se sigue DDD?



entity framework core repository pattern (4)

¿Por qué no usar dos repositorios?

var parent = ParentRepo.Get(parentId); parent.Children.Remove(childId); // remove it from the property Collection ChildRepo.Delete(childId); // delete it from the database ParentRepo.Commit(); // calls underlying context.SaveChanges()

Suponiendo que está compartiendo contextos a través de IOC / DI, la confirmación de llamada con un repo se confirmará para ambas, de lo contrario, llame a ChildRepo.Commit también.

Así que aquí está el escenario:

DDD indica que usa un repositorio para obtener la raíz agregada, luego la usa para agregar / eliminar a cualquier colección que tenga.

Agregar es simple, simplemente llame. .Add(Item item) en la Collection que desea agregar. Una nueva fila se agrega a la base de datos cuando guarda. Sin embargo, la eliminación es diferente: llamar a .Remove(Item item) no elimina el elemento de la base de datos, simplemente elimina la clave externa. Entonces, sí, sí, técnicamente ya no es parte de la colección, todavía está en la base de datos.

Al leer alrededor, la única solución es eliminarla usando el contexto de datos. Pero de acuerdo con DDD, el objeto de dominio no debe ser consciente del contexto de los datos, por lo que la eliminación tendrá que hacerse fuera del dominio.

¿Cuál es la forma correcta de hacer esto? ¿O es aceptable dejar la base de datos de huérfanos (tal vez ejecutar una rutina para eliminarlos)?


Al eliminar una entidad secundaria de una colección, EF la dejará como huérfana, eliminando solo la clave externa.

Si no desea eliminarlo explícitamente mediante el DbContext, puede usar lo que se llama "Relación de identificación" ( http://msdn.microsoft.com/en-us/library/ee373856.aspx en la parte inferior).

El truco consiste en establecer una clave primaria compuesta en el hijo, incluida la clave primaria del padre.

Una vez que haga eso, al eliminar la entidad de la colección principal, también se eliminará de la tabla.


No sé si esto es por diseño, pero si un objeto de detalle tiene una clave compuesta que contiene las columnas de la clave de su objeto maestro, se eliminará automáticamente si la elimina de la colección del objeto maestro. Si tiene un objeto Order con una clave OrderID y una propiedad de navegación de ICollection OrderLines, proporcione OrderLine una clave compuesta que contenga OrderID y OrderLineID.

Pero como no sé si puedo confiar en eso, la solución que he usado es dejar que EF lo maneje de la manera que lo hace, y corregir los objetos de detalle ''separados'' (no en términos de EF) en la llamada a SaveChanges (), enumerar sobre todas las entidades modificadas y cambiar el estado a eliminado según corresponda.


Resolví este problema en la aplicación en la que estoy trabajando actualmente usando eventos de dominio ; un concepto de DDD que Eric Evans dijo debería haber estado en su libro.

Si bien los objetos de dominio no pueden conocer el contexto del objeto, un IDomainEventHandler es: tengo un DomainObjectDeletionHandler que elimina los objetos "eliminados" del contexto del objeto antes de que el control vuelva a mi capa de aplicación y se guarden los cambios.

Para obtener más información, he escrito un blog sobre mi implementación de eventos de dominio y sobre cómo abordé uniendo todo.

Espero que ayude :)

Editar

Por ejemplo, si tiene una clase Order que tiene una colección OrderItems de tipo OrderItem :

public class Order { // Other stuff public void RemoveOrderItem(int orderItemId) { var orderItemToRemove = OrderItems.First(oi => oi.Id == orderItemId) OrderItems.Remove(orderItemToRemove); DomainEvents.Raise(new OrderItemRemoved(orderItemToRemove)); } }