2016-04-29 21 views
1

Automapper Projectionsを使用しているアプリケーションで自己参照モデルを処理する際に問題が発生しました。これは私のモデルの様子です。Automapper自己参照モデル投影

public class Letter 
{ 
    public int? ParentId {get; set;} 

    public Letter ParentLetter {get; set; 

    public int Id {get; set;} 

    public string Title {get; set;} 

    public string Content {get; set;} 

    public DateTime? ReceivedTime {get; set;} 

    public DateTime? SendingTime {get; set;} 

    public List<Destination> Destinations {get; set;} 

    public List<Letter> Responses {get; set;} 
} 

public class LetterView 
{ 
    public int? ParentId {get; set;} 

    public int Id {get; set;} 

    public string Title {get; set;} 

    public string Content {get; set;} 

    public DateTime? ReceivedTime {get; set;} 

    public DateTime? SendingTime {get; set;} 

    public List<DestinationView> Destinations {get; set;} 

    public List<LetterView> Responses {get; set;} 
} 


public class Destination 
{ 
    public int Id {get; set;} 

    public string Name {get; set;} 

    .. 
} 

public class DestinationView 
{ 
    public int Id {get; set;} 

    public string Name {get; set;} 
} 

// The mapping: 

CreateMap<Destination, DestinationView> 
CreateMap<Letter, LetterView> 

私の問題は、LetterViewにLetterViewをマッピングすることです。問題はレスポンスのどこかにありますが、私は何が変更されるべきかを理解できません。

単体テストを実行してマッピング設定をアサートすると、すべてが機能し、複数のレスポンスを持つ文字をビューモデルにマッピングすることができます。 しかし、データベースからのresposnes(Entity framework 6)で手紙を受け取ると、LetterViewへの投影によってstackoverflow例外がスローされます。

これはなぜ投影でのみ起こるのか誰にも教えてください。私は何を変えるべきですか?

+0

スタックオーバーフローのスタックトレースがありますか? –

答えて

0

DbContextでlazy loadingが有効になっている可能性があります。循環参照によってスタックオーバーフロー例外が発生することがあります。それを回避する最善の方法は、遅延読み込みを無効にすることです:

context.ContextOptions.LazyLoadingEnabled = false; 
// Bring entity from database then reenable lazy loading if needed 
context.ContextOptions.LazyLoadingEnabled = true; 

遅延ロードが非アクティブ化されている間EntityFrameworkはそれらを持ち帰っませんので、しかし、あなたはincludeに必要なすべてのナビゲーションプロパティが必要になります。他のリクエストに必要な場合は、再度有効にすることを忘れないでください。

1

ここにいくつかのオプションがありますが、通常は応答の最大深度を設定することをお勧めします。 AutoMapperはプロパティをスパイダリングしようとし、あなたは自己参照DTOを持っています。まず、次のように試してみてください:

CreateMap<Letter, LetterView>() 
    .ForMember(d => d.Responses, opt => opt.MaxDepth(3)); 

また、特定の深さでDTOを事前配線することもできます。 LetterViewとChildLetterViewを作成します。あなたのChildLetterViewはあなたのDTO側の正確な2レベルの深さを与える "応答"プロパティを持たないでしょう。これを深くすることができますが、親/子/孫/ Greatgrandchildの型名を持つ階層内のDTO型では非常に明示的に指定する必要があります。

+0

私は深度レベルが高いので、別のオブジェクトでこの明示的な設定をするとここでうまくいかないでしょう。私は最大の深さを設定しようとしました - ForMemberでそれを見つけることができませんでした、地図上でのみ。最大長の設定時に例外が発生する - 値はnullにできません。パラメータ名:body –

+0

また、問題に影響するかどうかわかりませんが、親文字もあります。質問に記載されているモデルに追加しました –