2013-07-13 65 views
6

我的問題是,有沒有可能對父對象和子對象有一個可能的Fluent NHibernate映射,它不需要具有父對象屬性的子對象?我還沒有想出如何將參考映射回父。當我按照原樣調用Create時,我得到一個異常,因爲Child對象沒有所需的外鍵(在數據存儲中是必需的)返回給Parent。在沒有對象屬性的情況下映射流暢NHibernate的外鍵

我有兩個POCO類:

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" 
    } 
} 

,並創建方法:

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

我希望能夠創建一個父對象有一個Child對象的列表,但沒有Child對象的引用返回到它們的Parent(除了父ID)。我想這樣做是爲了避免從Parent到Parent對象的循環引用,因爲這會導致JSON序列化的問題。

+0

是否將父屬性(在'Child')映射到專用字段的選項? –

+0

這就是我正在做的,雖然我試圖避免它,因爲我不能然後在'ParentId'屬性上運行查詢。似乎我應該能夠將外鍵約束屬性映射到列而不需要對象... –

+0

對於原始問題,Felipe的答案是正確的。不要直接序列化實體,首先將它們轉換爲DTO或ViewModel,首先獲得您想要的確切結構。 –

回答

3

可以毫無問題這些實體地圖,試試這個:

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"); 
    } 
} 

當你從ISession的獲得實體,不將其序列化到一定的格式,因爲這些都可以代替NHibernate的實體對象的代理。嘗試創建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'。 –

相關問題