Свойства коллекции 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.List
1 [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
; по сути, он обеспечивает такой же уровень защиты без необходимости привязки вашей модели к конкретной реализации коллекции. Смотрите эту статью для дальнейшего обсуждения.