Laden...

Warum wirft EF Core mit gemappten Entitäten eine "is already being tracked." Exception?

Erstellt von Duesmannr vor 3 Jahren Letzter Beitrag vor 3 Jahren 991 Views
D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 3 Jahren
Warum wirft EF Core mit gemappten Entitäten eine "is already being tracked." Exception?

verwendetes Datenbanksystem: <eig. MySQL>

Mahlzeit,

ich verwende AutoMapper um meine Entitäten von und zu DTO Entitäten zu mappen, funktioniert auch ohne Probleme.

Das Problem kommt erst, wenn ich dann mit der gemappten Entität arbeite.

Ich habe eine Translation Entity und eine Language Entity. (1:n)
Language hat n Translations.


Language language = applicationDbContext.Languages.FirstOrDefault(x => x.Name == "pl-t");
LanguageDTO mappedLanguage = new LanguageDTO();

mapper.Map(language, mappedLanguage);

//Input from ui
TranslationDTO translation = new TranslationDTO
{
    Identifier = "dtoTrans",
    Text = "dtoTrans",
    Language = mappedLanguage, //Does not work
    LanguageId = mappedLanguage.Id, //Works
    Id = Guid.NewGuid()
};

Translation trans = new Translation();
mapper.Map(translation, trans);

applicationDbContext.Translations.Add(trans); // Exception

Im Code Beispiel hole ich mir eine Language aus der Datenbank (Könnte auch eine neue erstellen, ist aber irrelevant) und mappe diese zu einem DTO.

Erstelle dann eine DTO Translation Entity (kommt bspw. von der UI) und würde dann im normalen Code die Navigation Property "Language" setzen und dann in der Datenbank erstellen.
Was ohne Mappen auch wunderbar funktioniert, mit Mapping erhalte ich diese Fehlermeldung:

Fehlermeldung:
The instance of entity type 'Language' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

Hab dazu den Thread auf Stackoverflow gefunden und den Aufruf der Map Methode wie in der Antwort geändert. Hatte das genau so wie sein 1. Beispiel (aus der Antwort).
Hilft auch nicht.

Setze ich aber nur die ID anstatt die ganze Entity, funktionierts.
Ich finde aber zu dem Problem explizit auch keine Lösung, wie man das Mappen umstellen soll.
Man kann die Entity dann noch De/-Attachen aber ist dann auch wieder mehr Aufwand.

Hier ist einmal das Git Repo. Ist ein Test Projekt, was diesen Fehler produziert.

Als explizite Frage nochmal. Was genau mache ich falsch bzw. was muss ich ändern, dass die Fehlermeldung nicht mehr erscheint?

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 3 Jahren

Moin,

wenn man keine Antworten erhält, versteht man entweder das Problem/die Frage nicht oder weiß keine Lösung.
Ersteres weiß ich nicht, wie ich es noch besser Beschreiben soll, weil ich mMn sehr viele Informationen liefere mit einem Git Repo, worin man das Problem reproduzieren kann.

Aber wer auch immer den Titel geändert hat, hat das Problem nicht verstanden.
Der Mapper wirft keine Exception, sondern EF Core beim Hinzufügen der Entity zum DbSet.

Hoffe trotzdem, dass jemanden evtl. was einfällt, weil mir tut es nicht, obwohl ich mich bis dato immer noch damit beschäftige.

Grüße

T
50 Beiträge seit 2010
vor 3 Jahren

So wie es ausschaut, hast Du ja das Objekt language aus der Datenbank (DataContext) geladen. Was im Mapper passiert, ist nicht transparent. Aber Du solltest Deinem translation-Objekt language und nicht mappedLanguage zuweisen. Die werden die identische Id haben und daher kommt die Meldung.

Normalerweise reicht es, die Id einer Referenz zuzuweisen und zu speichern, sofern der DataContext nur für den Zeitraum des Speicherns lebt. Wenn Du den DataContext länger leben lässt - wegen Caching oder ähnlichem - dann kommt man ggf. nicht drum herum auch die Referenz zu setzen. Ich persönlich vermeide es auf DataContext-Ebene zu cachen oder unnötig langlebig zu halten.

Auch verstehe ich nicht, warum die Language gemappt wird. Normalerweise sollte sich doch an dem Objekt in dem Kontext nichts ändern dürfen, oder doch? Die Frage wäre, ob dann die Language nicht ihre eigene Speichermethode bekommt.

5.657 Beiträge seit 2006
vor 3 Jahren

Aber wer auch immer den Titel geändert hat, hat das Problem nicht verstanden.

Du kannst den Titel jederzeit selbst anpassen. Dazu gibt es den Editieren-Button 😃

Das Problem selbst hat nichts mit dem AutoMapper zu tun. Der AutoMapper setzt nur Eigenschaftswerte entsprechend deiner Konfiguration.

Das Problem würde genauso auftreten, wenn du die Objekte manuell mappst und die einzelnen Werte per Hand setzt.

Weeks of programming can save you hours of planning