In unserem ziemlich komplexen DDD
Setup haben wir Datenmodelle und Domänenmodelle. Technisch sind sie ziemlich ähnlich mit Domänenmodellen, die normalerweise Additionseigenschaften haben. Wir verwenden Automapper
, um zwischen Daten und Domänenobjekten zu mappen. Das Problem ist, dass in einigen seltsamen Fällen, auf SaveAsync
wir in eine Stackoverflow exception
laufen. Hier ist der Code:Automapper Stackoverflow Ausnahme mit Entity Framework
1) public virtual async Task SaveAsync(TDomain item)
2) {
3) TData data = null;
4) if (default(TID).Equals(item.ID))
5) {
6) data = mapper.Map<TData>(item);
7)
8) dataContext.Set<TData>().Add(data);
9) }
10) else
11) {
12) data = dataContext.Set<TData>().Single(x => x.ID.Equals(item.ID));
13) if (data == null)
14) throw new Exception($"Unable to find {typeof(TData)} with ID {item.ID} in the database.");
15)
16) mapper.Map(source: item, destination: data);
17) }
18) await dataContext.SaveChangesAsync(userIdentity.ID);
19)
20) // Update the IDs of the item and its children
21) var domainTest = mapper.Map<TDomain>(data);
22) mapper.Map(source: domainTest, destination: item);
23) }
Wie Sie in Zeile 16 sehen, sind wir auf Daten von Element ohne Probleme zuordnen. Wir haben eine Testkarte in Zeile 21 hinzugefügt und die Karten sind in Ordnung. In Zeile 22 ist das Problem manchmal. In den meisten Fällen wird dies gut gespeichert und auf das TDomain-Element zurückversetzt. Wenn wir jedoch versuchen, eine Änderung an einem vorhandenen Objekt mit einem untergeordneten Objekt zu speichern, das auf das übergeordnete Objekt verweist, erhalten wir Stackoverflow exception
.
Ich habe untersucht, dies für eine ganze Weile und ich kann 2 Möglichkeiten sehen, die funktionieren könnte: 1) eine MaxDepth
auf die Config dieser Karte hinzufügen, so dass diese Rekursion nur so weit geht, aber das fühlt sich sehr hacky und Es fühlt sich an, als würde ich das Problem maskieren, das irgendwann in der Zukunft ein Wartungs-Albtraum werden könnte. Die andere Möglichkeit wäre, dass die SaveAsync
eine neue Instanz des Objekts (dh Zeile 21) zurückgibt, das fühlt sich deutlich besser an als die MaxDepth
Weise, fühlt sich aber immer noch etwas hacky an, als würde ich das eigentliche Problem vermeiden. Außerdem werden alle Werte in den Eigenschaften, die nur im Domänenmodell vorhanden sind, auf diese Weise gelöscht. Dies wäre auch ein ziemlich massiver Refactor, der fast 20 Apps betrifft, die jeweils 5 bis 20 Saves haben ... nicht dass ich mich beschwere. Vielleicht kann jemand darauf hinweisen, was ich tun kann, um dieses Problem zu beheben, oder vielleicht, was ich hier vermisse.
Nur wirklich klar sein, wenn Sie die Leitung 21 entfernen und ersetzen die Leitung 22 mit:
mapper.Map(source: data, destination: item);
Sie die gleiche Stackoverflow exception
erhalten.