Свойства коллекции Readonly, с которыми может работать NHibernate - PullRequest
4 голосов
/ 28 июля 2010

У моих классов доменов есть коллекции, которые выглядят так:

private List<Foo> _foos = new List<Foo>();
public virtual ReadOnlyCollection<Foo> Foos { get { return _foos.AsReadOnly(); } }

Это дает мне коллекции только для чтения, которые можно изменять из класса (т. Е. Используя поле _foos).

Эта коллекция отображается следующим образом (Свободный NHibernate):

HasMany(x => x.Foos).KeyColumn("ParentClassId").Cascade.All().Inverse().Access.CamelCaseField(Prefix.Underscore);

Теперь, когда я пытаюсь использовать эту коллекцию, я получаю:

Невозможно привести объект типа 'NHibernate.Collection.Generic.PersistentGenericBag 1[Foo]' to type 'System.Collections.Generic.List 1 [Foo]'.

Согласно Невозможно привести объект типа NHibernate.Collection.Generic.PersistentGenericBag к списку , это потому, что коллекция должна быть представлена ​​NHibernate в качестве интерфейса, чтобы NHibernate мог внедрить один из своих собственных Коллекционные классы.

В статье предлагается использовать вместо этого IList, но, к сожалению, этот интерфейс не включает метод AsReadOnly (), что портит мои планы по представлению только коллекции только для чтения для внешнего мира.

Кто-нибудь может подсказать, какой интерфейс я мог бы использовать вместо этого, другой подход, который соответствует тем же требованиям, или альтернативную карьеру, которая не вызывает такого большого разочарования?

Спасибо

David

Ответы [ 4 ]

7 голосов
/ 28 июля 2010

Метод AsReadOnly () - не единственный способ получить коллекцию ReadOnlyCollection.

private IList<Foo> _foos = new List<Foo>();
public virtual ReadOnlyCollection<Foo> Foos { get { return new ReadOnlyCollection<Foo>(_foos); } }

Еще один обруч прыгнул.

5 голосов
/ 28 июля 2010

Ваш ответ - хорошее решение, но я просто выставляю коллекции как IEnumerable<T>.При таком подходе существует небольшой риск, поскольку они могут быть возвращены обратно в IList.Является ли это приемлемым риском или нет, зависит от приложения.

3 голосов
/ 28 июля 2010

Из-за того, что IList не будет соответствовать вашим потребностям и что вы (к счастью) не используете Automapping, я бы назначил Foos защищенной / частной коллекцией IList «NHibernate-friendly», а затем создал бы общедоступнуюReadOnlyCollection, которая читает Foos.

Что-то вроде:

    protected IList<Foo> MappableFoos { get; set; }
    public ReadOnlyCollection<Foo> ReadOnlyFoos { get { return new ReadOnlyCollection<Foo>(MappableFoos) } }

    // Mapping file
    HasMany(x => x.MappableFoos ).KeyColumn("ParentClassId").Cascade.All().Inverse().Access.CamelCaseField(Prefix.Underscore);

Таким образом, единственным раскрытым свойством будет то, которое я смехотворно назвал " ReadOnlyFoos ".

1 голос
/ 28 июля 2010

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

...