2009-10-08 6 views
1

je vais utiliser quelques exemples de code pour montrer mon problème ...Nhibernate et WCF IList <> Conflit

c'est une entité

public class Channel : EntityBase 
{ 

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

canal local a une propriété de chaîne.

ce 2 classes mappé couramment et fonctionne bien avec la relation a beaucoup.

le problème est dans le service wcf.

lorsque je sélectionne un canal ou tous les canaux.

La liste localChannels est de taille fixe. (le type de ILIst qui retourne est un tableau typé)

Je veux que je sois une liste.

Nhibernate ne me laissera pas d'écrire ceci:

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

becuase il ne peut pas jeter ses collections à la liste

et ma procuration est écrit dans le code et non généré avec svcutil donc je ne peux pas changer le type de collection .

des solutions?

Répondre

5

Voir ma réponse à Manually change the ClientBase collection type from Array[] to List<>

La projection NHibernate et projection DataContract doivent être les mêmes? Je ne connais pas grand-chose à NHibernate, mais pouvez-vous faire quelque chose comme ça?

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

10x bonne idée .. Je pense que je viens d'utiliser l'utilitaire svc et éviter patch. –

-2
private IList<LocalChannel>channels; 

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

NHibernate sera en mesure d'utiliser IList mais votre interface publique peut utiliser Liste

+0

cela ne peut pas être fait car nhibernate implémente IList <> mais n'hérite pas de List, les Channels sont en fait un sac Persistance ou une autre implémentation de nhibernate. donc le casting est impossible, c'est pourquoi je ne peux pas utiliser la liste <> –

3

Il existe une alternative à la réponse acceptée si vous ne souhaitez pas utiliser plusieurs propriétés. Il profite de la façon dont WCF désérialise les propriétés. En utilisant la technique décrite dans this après, vous pouvez coder la classe comme suit:

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

J'aime réponse Sixto Saez. Juste avec une note: avec ceci, IList sera toujours de type Liste. De l'autre côté, le proxy NHibernate peut avoir sa propre collection qui hérite de IList < ...>. Ainsi, nous pouvons autoriser NHibernate à insérer sa collection, sauf dans le cas où la collection est de type array. Comme ça:

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