2010-02-24 90 views
2

我想控制我的域與集合的交互,所以我想我會使集合受到保護,並提供一個只讀封裝,以便內容可見,但我可以確保項目不會直接添加到集合。如何在(Fluent)NHibernate中添加只讀集合屬性?

所以我有以下代碼:

public class MyClass 
{ 
    public virtual ICollection<Thread> Threads 
    { 
     get { return new ReadOnlyWrappedCollection<Thread>(this.ThreadsInternal); } 
    } 

    protected virtual ICollection<Thread> ThreadsInternal { get; private set; } 
} 

我嘗試這樣做:

this.Map(c => c.Threads) 
      .Access.None(); 

結果被MappingException: Could not determine type for: System.Collections.Generic.ICollection'1[[Thread]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, for columns: NHibernate.Mapping.Column(Threads)

我嘗試這樣做:

this.HasMany(c => c.Threads) 
      .Access.None(); 

釷Ë結果的InvalidOperationException: Tried to add collection 'Threads' when already added

如果我省略了映射,我得到PropertyNotFoundException: Could not find a setter for property 'Threads' in class 'MyClass'

我怎樣才能說服NHibernate的忽略在映射這個屬性?我使用Fluent NHibernate,但也請在HBM中發佈示例。

回答

3

我不認爲你可以映射ICollection。無論如何,我遵循類似的模式,我發現映射它的最佳方式是映射一個私有的IList。

類別:

public class Invoice 
{ 
    private IList<InvoiceItem> _items; 

    public Invoice() 
    { 
     _items = new List<InvoiceItem>(); 
    } 

    public virtual IEnumerable<InvoiceItem> Items 
    { 
     get { return _items; } 
    }  
} 

映射:

public class InvoiceMap : ClassMap<Invoice> 
{ 
    public InvoiceMap() 
    { 
     Table("Invoice"); 

     HasMany(x => x.Items).KeyColumn("InvoiceId") 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Cascade.AllDeleteOrphan() 
      .Inverse() 
      .AsBag().LazyLoad(); 
    } 
} 

在映射的關鍵行是.Access.CamelCaseField(Prefix.Underscore)它告訴NHibernate的使用私有字段_items。請注意,集合仍然可以轉換爲IList,但如果需要,您可以將其包裝在只讀集合中。

+0

完美的作品,謝謝!順便提一下,您可以通過指定AsSet而不是AsBag來映射到ICollection。 – 2010-02-25 11:01:10

相關問題