2010-02-24 94 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

相关问题