2012-05-31 27 views
2

關係我有一個測試代碼:無法刪除的子實體在一個一對多NHibernate的

 using (var session = factory.OpenSession()) 
     { 
      var animalsCategory = session.Query<Category>().Where(c => c.Name == "Animals").Single(); 
      Assert.AreEqual(3, animalsCategory.Products.Count()); 
      animalsCategory.Products.ForEach(x => session.Delete(x)); 
      session.Flush(); 
     } 

和映射類別 & 產品類:

public class ProductMap : ClassMap<Product> 
{ 
    public ProductMap() 
    { 
     Id(x => x.ID); 
     Map(x => x.Name).Not.Nullable().Length(50); 
     Map(x => x.Description).Length(4000); 
     Map(x => x.UnitPrice).Not.Nullable(); 
     Map(x => x.ReorderLevel).Not.Nullable(); 
     Map(x => x.Discontinued); 

     References(x => x.Category).Not.Nullable(); 
    } 
} 

public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Id(x => x.ID); 
     Map(x => x.Name); 
     Map(x => x.Description); 
     HasMany<Product>(x => x.Products).Inverse().Cascade.AllDeleteOrphan(); 
    } 
} 

而且,這裏是類:

public class Product : Entity<Product> 
{ 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual Category Category { get; set; } 
    public virtual decimal UnitPrice { get; set; } 
    public virtual int ReorderLevel { get; set; } 
    public virtual bool Discontinued { get; set; } 
} 

public class Category : Entity<Category> 
{ 
    private List<Product> products = null; 

    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual IEnumerable<Product> Products { get { return products; } } 
} 

而現在,當我運行測試代碼我得到一個異常:

N * Hibernate.ObjectDeletedException:刪除的對象將通過級聯(移除協會刪除的對象)重新保存[Model.Product#1] *

這是很好的,我想我明白了:)

所以我創建了內部分類的方法類:

public virtual void ClearProducts() 
    { 
     products.Clear(); 
    } 

,我已經改變了我的測試代碼如下:

 using (var session = factory.OpenSession()) 
     { 
      var animalsCategory = session.Query<Category>().Where(c => c.Name == "Animals").Single(); 
      Assert.AreEqual(3, animalsCategory.Products.Count()); 
      //animalsCategory.Products.ForEach(x => session.Delete(x)); 
      animalsCategory.ClearProducts(); 
      session.Flush(); 
     } 

我把它換成的ForEachClearProducts電話。現在,我得到異常:

System.IndexOutOfRangeException:索引是該數組的範圍之外,在System.Array.Clear(陣列陣列,的Int32指數的Int32長度) 在System.Collections.Generic.List`1清除()

我也用while(products.Count> 0)循環來從集合中刪除所有產品,但我也有一個例外。有人可以告訴我,如果我無法從集合中刪除它們,我該如何刪除子對象?

感謝

編輯1:我驚呆了......我從剛變換類型的集合(和字段定義)的:

private List<Product> products = null; 

到:

private IList<Product> products = null; 

和代碼的作品。有人可以告訴我爲什麼嗎?

回答

2

問題1 - 你不能直接從子集合中刪除對象。爲了刪除它們,您將從Products中移除一個項目,然後保存父類別對象。所以用DDD術語來說,你只應該在aggregate root object上執行刪除,但你已經知道了。

問題#2 - 如果你正在使用延遲加載,你需要對你的公共實例成員虛擬關鍵字,並使用接口收集,讓NHibernate的可以與知道代理更換你的屬性如何延遲加載時第一次訪問。這裏有一個類似的question with a good answer

你確定你的Category和CategoryMap類現在看起來像那樣嗎?不確定像你這樣的映射在那裏有效,因爲你的公共屬性沒有setter,也沒有在映射中定義不同的訪問策略。

+0

我從VS複製/粘貼的代碼。感謝幫助。 – dragonfly

+0

我已經從Fluent導出映射,這是爲一對多關係映射XML的一部分: dragonfly

相關問題