2013-07-13 18 views
6

私の質問は、ChildオブジェクトにParentオブジェクトプロパティを持たせる必要のない、親オブジェクトと子オブジェクトのFluent NHibernateマッピングが可能ですか?私は参照を親にマップする方法を理解していません。現状のマッピングでCreateを呼び出すと、子オブジェクトに必要な外部キー(データストアで必須)が親に戻っていないため、例外が発生します。Fluentの外部キーをオブジェクトプロパティなしのNHibernateにマップする

私は2つのPOCOクラスがあります。私は、親オブジェクトを作成することができるようにしたい

public Parent Create(Parent t) 
{ 
    using (this.session.BeginTransaction()) 
    { 
     this.session.Save(t); 
     this.session.Transaction.Commit(); 
    } 
    return t; 
} 

public class Parent 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IList<Child> Childs { get; set; } 
} 

public class Child 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual int ParentId { get; set; } 
} 

そして、いくつかのマッピング:

public class ParentMap : ClassMap<Parent> 
{ 
    public ParentMap() 
    { 
     this.Table("Parents"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.HasMany(x => x.Childs).KeyColumn("ChildId").Cascade.AllDeleteOrphan(); 
    } 
} 

public class ChildMap : ClassMap<Child> 
{ 
    public ChildMap() 
    { 
     this.Table("Childs"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     // Needs some sort of mapping back to the Parent for "Child.ParentId" 
    } 
} 

とメソッドを作成しますChildオブジェクトのリストを持っていますが、Childオブジェクトに親(親ID以外)の参照が戻っていません。 JSONのシリアライゼーションに問題が発生しているため、ParentからChildへの循環参照がParentオブジェクトに戻ってくるのを避けるために、これを実行したいと思います。

+0

親プロパティ( 'Child')のプライベートフィールドをオプションにマッピングしていますか? –

+0

これは私がやっていることですが、 'ParentId'プロパティでクエリを実行できないので、避けようとしています。オブジェクトを必要とせずに、外部キー制約付きのプロパティを列にマップできるはずです。 –

+0

元の質問の場合、Felipeの答えは正しいです。エンティティを直接シリアル化しないで、最初にDTOまたはViewModelに変換し、最初に必要な構造を取得します。 –

答えて

3

あなたは問題なくこれらのエンティティをマッピングすることができ、これを試してください:あなたはISessionからエンティティを取得すると、これらは代わりにNHibernateはエンティティオブジェクトのプロキシのことができるので、

public class ParentMap : ClassMap<Parent> 
{ 
    public ParentMap() 
    { 
     this.Table("Parents"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.HasMany(x => x.Childs).KeyColumn("ChildId").Cascade.AllDeleteOrphan(); 
    } 
} 

public class ChildMap : ClassMap<Child> 
{ 
    public ChildMap() 
    { 
     this.Table("Childs"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.Map(x => x.ParentId); 
     // if you have a reference of Parent object, you could map as a reference, for sample: 
     this.References(x => x.Parent).Column("ParentId"); 
    } 
} 

は、いくつかの形式にシリアライズしないでください。 DTO (Data Transfer Object) classesを作成し、これらのエンティティをDTOオブジェクトに変換してシリアル化してください。あなたは循環参照を避けるでしょう。サンプルについて:

public class ParentDTO 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int ParentId { get; set; } 

    /* here you just have the primitive types or other DTOs, 
     do not reference any Entity type*/ 
} 

そして、あなたはシリアル化された価値を共有するための値を読んでする必要があります。

var dto = ISession.Query<Parent>() 
        .Select(x => 
         new ParentDTO() { 
          Id = x.Id, 
          Name = x.Name, 
          ParentId = x.ParentId) 
        .ToList(); 

は、データアクセス層から、この結果を取得し、サンプルのため、シリアライズしてみてください:

var result = Serialize(dto); 
+1

あなたの答えが解決してくれない重要な点は、 'ParentId'プロパティが' Parent'オブジェクトの 'Id'プロパティに外部キー制約を持っていなければならないということです。あなたはそれをマップしているだけなので、まったく制約はありません。 –

+0

私はあなたと@PatrickQuirkを交渉しますが、提供されるOPには参照がないモデルでは、Idだけがあります。 –

関連する問題