Nhibernate和WCF IList<>冲突

时间:2009-10-08 16:08:19

标签: wcf fluent-nhibernate

我将使用一些示例代码来演示我的问题...

这是一个实体

public class Channel : EntityBase
{

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

本地频道有字符串属性。

这两个类流畅地映射并且与许多关系工作正常。

问题出在wcf服务中。

当我选择频道或所有频道时。

localChannels列表是固定大小的。 (返回的ILIst的类型是类型化数组)

我希望自己成为名单。

Nhibernate不会让我写这个:

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

因为它无法将他的藏品投射到List

我的代理是用代码编写的,不是用svcutil生成的,所以我不能改变集合类型。

任何解决方案?

4 个答案:

答案 0 :(得分:5)

请参阅我对Manually change the ClientBase collection type from Array[] to List<>

的回答

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

答案 1 :(得分:3)

如果您不想使用多个属性,则可以使用已接受答案的替代方法。它利用了WCF如何反序列化属性。使用this post中描述的技术,您可以按如下方式对类进行编码:

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

答案 2 :(得分:1)

我喜欢Sixto Saez的回答。只需一个注释:有了这个,IList将始终是List类型。另一方面,NHibernate代理可以拥有自己的集合,继承IList&lt; ...&gt;。因此,我们可以允许NHibernate插入他的集合,除非集合是类型数组。像这样:

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

答案 3 :(得分:-2)

private IList<LocalChannel>channels;

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

NHibernate将能够使用IList,但您的公共接口可以使用List