2011-07-21 35 views
0

我有以下類:功能NHibernate - 不能添加的項目與持久性數據的hasMany關係

public class Client { 
    public virtual Guid ClientID { get; set; } 
    public virtual string ClientName { get; set; } 
    public virtual IList<ClientMonthlyRevenue> Revenue { get; set; } 

    ... 
    public virtual void SetMonthlyRevenue(int year, int month, double revenue) 
    { 
     // Make sure it's not null... this might happen depending on how the client is created  
     if (Revenue == null) 
     Revenue = new List<ClientMonthlyRevenue>(); 

     // Check for existance - we don't want any duplicates   
     ClientMonthlyRevenue clientMonthlyRevenue = Revenue.Where(x => x.Year == year && x.Month == month).FirstOrDefault();   
     if (clientMonthlyRevenue == null)   
     { 
      // If it doesn't exist, create a new one and add to the list 
      clientMonthlyRevenue = new ClientMonthlyRevenue(this, year, month, revenue); 
      this.Revenue.Add(clientMonthlyRevenue); // This is the line throwing the error 
     } 
     else 
     { 
      // If it exists, just update it 
      clientMonthlyRevenue.Revenue = revenue; 
     } 
    } 
} 

public class ClientMonthlyRevenue { 
    public virtual Client ParentClient { get; set; } 
    public virtual int Year { get; set; } 
    public virtual int Month { get; set; } 
    public virtual double Revenue { get; set; } 

    ... 
} 

而這兩個映射:

public class ClientMap : ClassMap<Client> 
{ 
    Id(x => x.ClientID).GeneratedBy.Assigned(); 
    Map(x => x.ClientName); 

    HasMany<ClientMonthlyRevenue>(x => x.Revenue) 
     .Table("ClientMonthlyRevenue") 
     .KeyColumn("ClientID") 
     .Cascade.All() 
     .Fetch.Join(); 
} 

public class ClientMonthlyRevenueMap : ClassMap<ClientMonthlyRevenue> 
{ 
    CompositeId() 
     .KeyReference(x => x.Client, "ClientID") 
     .KeyProperty(x => x.Year) 
     .KeyProperty(x => x.Month); 

    Map(x => x.Revenue); 
} 

當我從一開始客戶端數據庫:

Client client = Session.Get<Client>(clientID); 

所有的數據都在那裏,這很好。但是,當我嘗試添加一個新的ClientMonthlyRevenue孩子:

client.Revenue.Add(new ClientMonthlyRevenue(this.ClientID, year, month, revenue)); 

我得到的錯誤:

Collection was of a fixed size. 

我錯過或誤解這裏的東西?而我需要做什麼修改,以便能夠將項目添加到這個列表堅持?

+0

您可以包括堆棧跟蹤?我能夠創建這個樣本,它爲我工作得很好嗎? – codeprogression

+0

堆棧跟蹤是很無趣......它指向客戶端類(我加了函數引發錯誤)的指示線,低於這只是我的程序 –

回答

1

我會改變客戶對象有以下幾點:

public class Client 
{ 
    public Client() 
    { 
     Revenue = new List<ClientMonthlyRevenue>(); 
    } 

    public virtual Guid ClientID { get; set; } 
    public virtual string ClientName { get; set; } 
    public virtual IList<ClientMonthlyRevenue> Revenue { get; set; } 

    public virtual void AddRevenue(ClientMonthlyRevenue revenue) 
    { 
     revenue.ParentClient = this; 
     Revenue.Add(revenue); 
    } 
} 

然後,你可以這樣調用:

public void TestMapping() 
{ 
    session.BeginTransaction(); 
    var client = new Client{ClientID = Guid.NewGuid()}; 
    session.SaveOrUpdate(client); 

    client = session.Get<Client>(client.ClientID); 
    client.AddRevenue(new ClientMonthlyRevenue(2001,07,1200)); 
    session.Transaction.Commit(); 
} 

錯誤您收到聽起來像它可以創建在堆棧中較高。我能夠重新創建你的場景。查看全部來源:https://gist.github.com/1098337

+0

你是正確的。一些挖後,我想通了,這是正由自動的序列化對象繼承掉了幾個類中的某些巫術的框架代碼引起的 - 當列表中得到了序列化,它,它轉換爲靜態大小的數組。 –

+0

高興你發現了它。 – codeprogression

0

你試圖標記您的收藏作爲反?我不知道它是否可以幫助。

HasMany<ClientMonthlyRevenue>(x => x.Revenue) 
    .Table("ClientMonthlyRevenue") 
    .KeyColumn("ClientID") 
    .Cascade.All() 
    .Fetch.Join() 
    .Inverse(); 
+0

我希望客戶端控制ClientMonthlyRevenue對象,這樣我永遠需要明確保存子對象。 –

+0

添加逆()只是改變哪個映射控制保存。通過調用Cascade.All()你clientmap仍在煽動保存,但推遲保存操作的revenuemap。這使得生成的sql有所不同。如果沒有反轉,你會看到一堆DELETE操作,然後是INSERT操作。反過來,你會看到一個INSERT操作。 – codeprogression

+0

哇,我完全誤解了逆()是爲..謝謝!可悲的是,這並沒有幫助解決問題。 –