Nhibernate and WCF IList<> Conflict

a 夏天 提交于 2020-01-14 03:47:07

问题


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?


回答1:


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



回答2:


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



回答3:


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



回答4:


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



来源:https://stackoverflow.com/questions/1538811/nhibernate-and-wcf-ilist-conflict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!