0

Dans notre configuration assez complexe DDD nous avons des modèles de données et des modèles de domaines. Techniquement, ils sont assez similaires avec les modèles de domaine ayant généralement des propriétés supplémentaires. Nous utilisons Automapper pour mapper entre les objets de données et de domaine. Le problème est que dans certains cas étranges, sur SaveAsync nous courons dans un Stackoverflow exception. Voici le code:Automapper Stackoverflow exception avec 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) } 

Comme vous pouvez le voir sur la ligne 16, nous effectuons un mappage vers les données de l'élément sans aucun problème. Nous avons ajouté une carte de test à la ligne 21 et les cartes sont très bien. Sur la ligne 22 est où le problème est PARFOIS. Dans la plupart des cas, cela enregistre très bien et renvoie à l'élément TDomain très bien ... mais lorsque nous essayons d'enregistrer une modification à un objet existant qui a un enfant qui référence l'objet parent, nous obtenons ce Stackoverflow exception. J'ai fait des recherches sur cela pendant un certain temps et je peux voir 2 options qui pourraient fonctionner: 1) ajouter un MaxDepth à la config de cette carte de sorte que cette récursivité ne va que jusqu'à présent, mais cela se sent très hacky et J'ai l'impression de masquer le problème qui pourrait devenir un cauchemar de maintenance dans le futur. L'autre option serait pour le SaveAsync de retourner une nouvelle instance de l'objet (c'est-à-dire, la ligne 21) cela semble certainement bien mieux que le MaxDepth mais se sent toujours un peu hacky, comme j'évite le vrai problème. En outre, toutes les valeurs dans les propriétés qui existent uniquement dans le modèle de domaine seront effacées de cette façon. Ce serait aussi un refactor assez massif qui toucherait presque 20 applications, chacune ayant 5 à 20 sauvegardes ... pas que je me plains. Peut-être que quelqu'un peut indiquer ce que je peux faire pour résoudre ce problème ou peut-être ce qui me manque ici.

Juste pour être vraiment clair, si vous supprimez la ligne 21 et de remplacer la ligne 22 avec:

mapper.Map(source: data, destination: item); 

vous obtenez le même Stackoverflow exception.

Répondre

0

Pour l'instant, j'ai ajouté un paramètre optionnel bool is.... = true à la méthode de sauvegarde, et j'évalue la ligne 22 uniquement si ce paramètre est vrai. Dans les cas où je vais dans cette récursion infinie, je passe un false ... Je sais que c'est vraiment hacky donc j'espère que quelqu'un répond avec une solution réelle ... mais cela me permet de continuer dans mon projet