Entfernen Sie ein Element aus der Sammlung mit Entity Framework
Ich bin mit DDD. Ich habe ein Klasse Produkt, welches ein Aggregat root.
public class Product : IAggregateRoot
{
public virtual ICollection<Comment> Comments { get; set; }
public void AddComment(Comment comment)
{
Comments.Add(comment);
}
public void DeleteComment(Comment comment)
{
Comments.Remove(comment);
}
}
Die Schicht hält, die die Modelle gar nicht kennt, EF überhaupt. Das problem ist, dass wenn ich Anrufe DeleteComment(comment)
EF wirft Ausnahme
Einer Beziehung von der "Product_Comments' AssociationSet wird in der "Gelöscht" Status. Angesichts Vielzahl von Einschränkungen, eine entsprechende 'Product_Comments_Target' muss auch in den "Gelöschten" Zustand.
Selbst wenn das element aus der Auflistung entfernt, EF nicht löschen. Was sollte ich tun, um dies zu beheben, ohne zu brechen DDD? (Ich bin denken auch daran, ein repository für die Kommentare als gut, aber nicht rechts)
- Code Beispiel:
Weil ich bin versucht, DDD, die Product
ist ein aggregate root, und es hat ein repository IProductRepository
. Kann kein Kommentar vorhanden ist, ohne Produkt, daher ist eine Kinder Product
Aggregat, und Product
ist verantwortlich für die Erstellung und das löschen von Kommentaren. Comment
nicht über ein Repository.
public class ProductService
{
public void AddComment(Guid productId, string comment)
{
Product product = _productsRepository.First(p => p.Id == productId);
product.AddComment(new Comment(comment));
}
public void RemoveComment(Guid productId, Guid commentId)
{
Product product = _productsRepository.First(p => p.Id == productId);
Comment comment = product.Comments.First(p => p.Id == commentId);
product.DeleteComment(comment);
//Here i get the error. I am deleting the comment from Product Comments Collection,
//but the comment does not have the 'Deleted' state for Entity Framework to delete it
//However, i can't change the state of the Comment object to 'Deleted' because
//the Domain Layer does not have any references to Entity Framework (and it shouldn't)
_uow.Commit(); //UnitOfWork commit method
}
}
- Scheint, dass Sie nicht aufrufen EF-s SaveChanges
- Ich denke, es gibt eine Tabelle namens Ziel. Diese Tabelle hat FK Verweis auf Kommentare Tabelle. Wenn Sie versuchen, eine Zeile zu löschen in der Kommentar-Tabelle, die Mitarbeiterin Zeilen in Ziel müssen zuerst gelöscht werden.
- Ich bekomme diese Fehlermeldung, wenn ich rufen Sie SubmitChanges()
- Nein, ich habe keine Tabelle, ich denke, das ist eine Standard-Beziehung-name erstellt von Entity Framework. (Ich bin mit Code First)
- Können Sie erklären, mehr code?
- BTw, du bist nicht mit DDD (zumindest die Frage hat keinen Bezug zu DDD), bist du mit EF. Bitte nicht Modell Ihrer Domäne auf der Oberseite des EF oder je nach EF oder anderen ORM oder Persistenz detail
- Ich fügte hinzu, ein anderes Beispiel, ich hoffe, es ist nützlich.
- Domain-Schicht weiß nichts von Entity Framework. Domain-Layer funktioniert einfach mit Repositories und UnitOfWork.
- Können Sie auch zeigen Sie uns Ihre Zuordnung? Ich kann deinen Fehler reproduzieren.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe eine Menge Leute gesehen, die Meldung dieses Problems. Es ist eigentlich ganz einfach zu beheben, aber lässt mich denken, dass es ist nicht genug, eine Dokumentation, wie EF wird erwartet, dass sich in dieser situation Verhalten.
Trick: Beim Aufbau der Beziehung zwischen Eltern und Kind, Sie ' ll HABEN, UM eine "composite" - Taste auf das Kind. Auf diese Weise, wenn Sie sagen, die Eltern zu löschen, 1 oder alle seine Kinder, die verwandten Datensätze tatsächlich aus der Datenbank gelöscht werden.
Konfigurieren zusammengesetzten Schlüssel, der mit Fluent API:
Dann löschen Sie die zugehörigen Kinder:
Getan!
Hier zwei Verwandte Lösungen:
Löschen von Abhängigen Entitäten, die, Wenn Sie Entfernt Von EF Collection
Ich gesehen habe 3 Ansätze zur Umgehung dieser Mangel EF:
DbContext
'sSaveChanges()
und Griff die Löschung dort (wie pro Euphorische Antwort)Mir gefällt option 3 am besten, weil es erfordert keine änderungen an Ihrer Datenbank-Struktur (1) oder Ihre domain-Modell (2), sondern er legt Sie die Problemumgehung, die in der Komponente (EF), hatte der Mangel in den ersten Platz.
Also dies ist eine aktualisierte Lösung entnommen Euphorische Antwort/blog-post:
Hinweis: dies setzt Voraus, dass
ParentProduct
ist die navigationseigenschaft aufComment
zurück zu seinem BesitzProduct
.Löschen Sie den Kommentar aus der Produkt mit Ihrem Ansatz löscht nur die Zuordnung zwischen Produkt und Kommentar. So dass der Kommentar noch vorhanden ist.
Was Sie tun müssen, ist zu sagen, die ObjectContext, der Kommentar ist auch gelöscht mit der Methode
DeleteObject()
.Den Weg, den ich tun es ist, dass ich die Update-Methode von meinem repository (weiß, Entity Framework) zu überprüfen gelöscht Verbände und auch löschen, die veraltet Entitäten. Sie können dies tun, indem Sie mit dem ObjectStateManager des ObjectContext.
Beispiel:
Ich entschieden habe das gleiche problem durch die Schaffung einer übergeordneten Attribut für meine Modelle und überprüfen Sie das Attribut in der SaveChanges-Funktion. Ich habe geschrieben, ein blog über dies: http://wimpool.nl/blog/DotNet/extending-entity-framework-4-with-parentvalidator