0

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.

Antwort

0

Für jetzt habe ich einen optionalen Parameter bool is.... = true der Speichermethode hinzugefügt, und ich evaluiere Zeile 22 nur, wenn dieser Parameter wahr ist. In den Fällen, in denen ich in diese unendliche Rekursion gehe, passiere ich eine false ... Ich weiß, das ist wirklich hacky, also hoffe ich, dass jemand mit einer tatsächlichen Lösung antwortet ... aber das lässt mich in meinem Projekt weitergehen

Verwandte Themen