Chen Kinnrot
Chen Kinnrot

Reputation: 21015

Nhibernate and WCF IList<> Conflict

i'll use some sample code to demonstrate my problem...

this is an entity

public class Channel : EntityBase
{

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

local channel has a string property.

this 2 classes mapped fluently and works fine with the has many relation.

the problem is in the wcf service.

when i'm selecting a channel or all channels.

the localChannels list is fixed size. (the type of ILIst that returns is typed array)

i want i to be a List.

Nhibernate wont let me to write this:

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

becuase it cant cast his collections to List

and my proxy is written in code and not generated with svcutil so i cant change the collection type.

any solutions?

Upvotes: 1

Views: 2553

Answers (4)

vllado2
vllado2

Reputation: 180

I like Sixto Saez answer. Just with one note: with this, IList will always be of type List. On other side, NHibernate proxy can have his own collection which inherits IList<...>. So, we can allow NHibernate to insert his collection, except in case when collection is of type array. Like this:

    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;
        }
    }

Upvotes: 1

Sixto Saez
Sixto Saez

Reputation: 12680

There is an alternative to the accepted answer if you don't want to use multiple properties. It takes advantage of how WCF deserializes properties. Using the technique described in this post, you could code the class as follows:

        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);}
            }
        }

Upvotes: 3

Adam Fyles
Adam Fyles

Reputation: 6050

private IList<LocalChannel>channels;

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

NHibernate will be able to use IList but your public interface can use List

Upvotes: -2

Eugene Osovetsky
Eugene Osovetsky

Reputation: 6541

See my answer to Manually change the ClientBase collection type from Array[] to List<>

Does the NHibernate projection and DataContract projection have to be the same? I don't know much about NHibernate, but can you do something like this?

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;}
}

Upvotes: 6

Related Questions