Как добавить свойство коллекции только для чтения в (Свободно) NHibernate? - PullRequest
2 голосов
/ 24 февраля 2010

Я хочу контролировать взаимодействие своего домена с коллекцией, поэтому я решил защитить коллекцию и предоставить оболочку, доступную только для чтения, чтобы ее содержимое было видно, но я могу гарантировать, что элементы не добавляются напрямую в коллекцию.

Итак, у меня есть следующий код:

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.

1 Ответ

3 голосов
/ 25 февраля 2010

Я не думаю, что вы можете отобразить 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, но при необходимости вы можете поместить ее в коллекцию только для чтения.

...