Nhibernate и WCF IList ‹› Конфликт

я воспользуюсь образцом кода, чтобы продемонстрировать свою проблему ...

это сущность

public class Channel : EntityBase
{

    [DataMember]
    public virtual IList<LocalChannel> LocalChannels { get; set; }
}

локальный канал имеет строковое свойство.

эти 2 класса свободно отображаются и отлично работают с множеством отношений.

проблема в сервисе wcf.

когда я выбираю канал или все каналы.

список localChannels имеет фиксированный размер. (тип возвращаемого ILIst - это типизированный массив)

Я хочу быть Списком.

Nhibernate не позволяет мне писать это:

public virtual List<LocalChannel> LocalChannels { get; set; }

потому что он не может добавить свои коллекции в список

и мой прокси написан в коде, а не сгенерирован с помощью svcutil, поэтому я не могу изменить тип коллекции.

любые решения?


person Chen Kinnrot    schedule 08.10.2009    source источник


Ответы (4)


См. Мой ответ на Вручную измените тип коллекции ClientBase из массива [] в список ‹›

Должны ли быть проекции NHibernate и DataContract одинаковыми? Я мало что знаю о NHibernate, но можно ли сделать что-то подобное?

public class Channel : EntityBase{

  //For WCF
  [DataMember(Name="LocalChannel")]
  private List<LocalChannel> LocalChannelsPrivate {
     get {return new List<LocalChannel>(LocalChannels);}
    set {LocalChannels=value;}
  }

  //For NHibernate
  public virtual IList<LocalChannel> LocalChannels {get; set;}
}
person Eugene Osovetsky    schedule 09.10.2009
comment
10x хорошая идея .. я думаю, что просто использую утилиту svc и избегаю патчей. - person Chen Kinnrot; 09.10.2009

Если вы не хотите использовать несколько свойств, есть альтернатива принятому ответу. Он использует то, как WCF десериализует свойства. Используя технику, описанную в этом сообщении, вы можете закодировать класс следующим образом:

        public class Channel : EntityBase{

            //Initialize backing var to an empty list or null as desired.
            private IList<LocalChannel> _localChannels = new List<LocalChannel>();

            //For WCF & NHibernate:
            [DataMember]
            public virtual IList<LocalChannel> LocalChannels
            {
                get {return _localChannels;}
                set {_localChannels = new List<LocalChannel>(value);}
            }
        }
person Sixto Saez    schedule 28.06.2010

Мне нравится ответ Сиксто Саеза. Только с одним примечанием: при этом IList всегда будет иметь тип List. С другой стороны, прокси NHibernate может иметь свою собственную коллекцию, которая наследует IList ‹...>. Итак, мы можем разрешить NHibernate вставить свою коллекцию, за исключением случая, когда коллекция имеет тип array. Нравится:

    private IList<LocalChannel> _localChannels ;
    [DataMember]
    public virtual IList<LocalChannel> LocalChannels {
        get
        {
            return _localChannels ?? (_localChannels = new List<LocalChannel>());
        }
        set
        {
            _localChannels = value.GetType() == typeof(LocalChannel[])
                                ? new List<LocalChannel>(value)
                                : value;
        }
    }
person vllado2    schedule 18.09.2011

private IList<LocalChannel>channels;

public List<LocalChannel>Channels{ get { return this.channels as List<LocalChannel>; } set{ this.channels = value;}

NHibernate сможет использовать IList, но ваш публичный интерфейс может использовать List

person Adam Fyles    schedule 09.10.2009
comment
это невозможно сделать, потому что nhibernate реализует IList ‹›, но не наследует List, каналы на самом деле являются сумкой Persistance или какой-либо другой реализацией коллекции nhibernate. поэтому приведение невозможно, поэтому я не могу использовать List ‹› - person Chen Kinnrot; 09.10.2009