Свойства коллекции Readonly, с которыми может работать NHibernate

Мои классы доменов имеют коллекции, которые выглядят так:

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.PersistentGenericBag1[Foo]' to type 'System.Collections.Generic.List1 [Foo]".

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

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

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

Спасибо

Дэвид

4 ответа

Решение

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

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

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

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

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

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

    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".

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

Другие вопросы по тегам