かなり複雑なDDD
セットアップでは、データモデルとドメインモデルが用意されています。技術的には、通常追加プロパティを持つドメインモデルとかなり似ています。 Automapper
を使用して、データオブジェクトとドメインオブジェクトをマッピングします。問題は、いくつかの奇妙なケースでは、SaveAsync
にStackoverflow exception
が入っていることです。コードは次のとおりです。Entity FrameworkのAutomapper Stackoverflow例外
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) }
16行目から分かるように、私たちは問題のないデータをマッピングしています。私たちは21行目のテストマップを追加しました。 22行目で問題が起こっています。ほとんどの場合、TDomain項目にはうまく保存されてマップされますが、親オブジェクトを参照する子を持つ既存のオブジェクトに変更を保存しようとすると、Stackoverflow exception
となります。
私はかなり長い間これを研究してきましたが、2つのオプションがあります:1)このマップの設定にMaxDepth
を追加して、この再帰が今のところ行っているだけですが、私は潜在的に将来的にメンテナンスの悪夢になる可能性のある問題を隠しているように感じます。もう1つのオプションは、SaveAsync
がオブジェクトの新しいインスタンス(つまり、21行目)を返すことです。これは確かにMaxDepth
の方法よりも優れていますが、実際の問題を回避しているように、ちょっとハッキリしています。また、ドメインモデルにのみ存在するプロパティの値は、この方法で消去されます。これはまた、それぞれが5〜20人のセーブを持つほぼ20のアプリに影響を与える、かなり大規模なリファクタリングになるでしょう...私が不平を言っているわけではありません。おそらく、誰かが私が実際にこの問題を解決するために何ができるのか、おそらく私がここで欠けているものを指摘することができます。
あなたがライン21を削除し、とライン22交換した場合だけで、本当に明確にする:あなたは同じStackoverflow exception
を得る
mapper.Map(source: data, destination: item);
を。