IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entity Framework Discussion :

EF : Relation N-N avec une table de référence


Sujet :

Entity Framework

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut EF : Relation N-N avec une table de référence
    Bonjour à tous,

    Je rencontre un problème avec Entity Framework au niveau d'une relation.

    J'ai une table Client qui contient une liste de client. J'ai une table Type qui contient la liste des types de client possible. C'est une table de référence.

    Enfin, j'ai une table TypeClient qui fait la liaison entre ces deux tables.

    En effet, un client peut être d'un ou plusieurs types à la fois. Il n'est donc pas possible de stocker l'id du type directement dans la table Client. La table intermédiaire est nécessaire.

    Côté EF, cette table intermédiaire a été automatiquement symbolisée par une relation entre Client et Type. On ne voit pas l'entity "TypeClient".

    Mon problème vient au moment ou je souhaite mettre un jour un Client. Imaginons que je souhaite ajouter à ce Client un Type, ou que je souhaite lui en retirer un, je vois pas comment faire.

    Si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    context.Comptes.Attach(unClient);
    context.ObjectStateManager.ChangeObjectState(unClient, EntityState.Modified);
    ....
    context.ObjectStateManager.ChangeObjectState(item, EntityState.Added);
    context.SaveChanges;
    sur l’élément (Item) de la propriété de Navigation "Types" du Client, comment EF sait qu'il faut ajouter une ligne dans la table TypeClient mais pas dans la table Type qui est une table de référence (on doit rien faire sur cette table).

    Y'a un truc qui m’échappe à ce niveau là.

    De même, comment faire pour supprimer une ligne dans TypeClient sans qu'EF n'essaye de supprimer aussi dans Type ?

    Si j'essaye de faire simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    context.ObjectStateManager.ChangeObjectState(item, EntityState.Deleted);
    context.SaveChanges;
    J'obtiens un joli message d'erreur.


    Enfin, j'ai essayé de remplacer l'association par une véritable Entité mappée sur la table TypeClient et j'ai ensuite relié cette entité à Client et Type. Mais visiblement, il aime pas trop. Si je tente de valider, il me dit :

    Problem in mapping fragments starting at line 1057
    Each of the following columns in table TypeClient is mapped to multiple conceptual side properties:
    TypeClient.IdCli is mapped to <ClientTypeClient.TypeClient.IdCli, ClientTypeClient.Client.IdCli>
    Y'a surement un qui qui m'échappe. Merci d'avance pour votre aide.
    Dernière modification par Deepin ; 20/01/2011 à 11h15. Motif: Balises [QUOTE]...[/QUOTE] au lieu de [CODE]...[/CODE]

  2. #2
    Invité
    Invité(e)
    Par défaut
    Je précise que c'est une application utilisant WCF.

    Côté Client, je ne suis pas sur le context donc. J'envoie un objet Client avec une liste de paramètre au service et sur le service, je ré attache le client au context.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Salut,

    pour ajouter un nouveau type à un client, normalement EF t'as créé une collection d'objet de type TypeClient donc normalement tu fais ça :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    client.Types.Add(ton nouveau type | un type déjà existant dans la base);

    Pour supprimer un type associé à un client :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    client.Types.Remove(un type déjà existant dans la base);

    Toutes les opérations d'ajout ou de suppression d'un type (déjà existant dans la base de données) à la collection Types d'un client n'entraîne pas de modifications au niveau de ta table TypeClient.
    Par contre si tu crées un nouveau TypeClient et que tu l'ajoutes juste après à la collection Types d'un client, alors EF crées d'abords ce type dans la table TypeClient avant de l'associer au client donc avant de créer la jointure dans la base de données.

    Bon je ne sais pas si j'ai bien expliqué.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Merci pour ta réponse.

    Si, c'est très clair.

    J'ai fais un essai sur ma méthode UpdateClient sur le Service WCF :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var result = context.Types.Where(par => par.IdTyp == 165).FirstOrDefault();
    unClient.Types.Add(result);
    Effectivement, ça marche. EF voit bien que le Type existe dans la table Type, il ajoute juste une ligne dans TypeClient.

    Idem si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unClient.Types.Remove(result);
    Mais le problème, c'est que j'ajoute et supprime des éléments à la liste des Types du Client côté client justement ! Côté Service WCF, j'attache mon objet Client à mon context. Par défaut, EF ne sait pas ce qui a été ajouté, modifié, supprimé. Il faut lui préciser manuellement en précisant les états. Mais comment ?

    Si je met un élément de la liste des Type d'un Client dans l'état "Added" ou "Deleted", il ne comprend pas. Pour lui, ça veut dire qu'il faut le créer ou le supprimer de la table Type.

    Je sais pas si je suis trés clair

  5. #5
    Invité
    Invité(e)
    Par défaut
    Deux méthodes :
    • La plus simple c'est d'abords de récupérer le client correspondant à partir du context de données EF et à partir ce dernier tu supprimes tous les types clients qui lui sont asociés. Ensuite tu parcours les types clients que tu récois via WCF.
      Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
       
      clientEntity.TypeClients.Clear();
      foreach(TypeClient type in clientWCF.TypeClients)
      {
      	clientEntity.TypeClients.Add(type);
      }
    • La plus complexe c'est d'abords de récupérer le client correspondant à partir du context de données EF et tu parcours la liste des types clients de ce dernier et tu supprimes ceux qui ne sont plus dans les types clients passés via WCF. Ensuite tu parcours les types clients passés via WCF et tu inséres ceux qui n'existe pas dans le contexte de données.


    Bon, moi perso j'ai toujours utilisé la première méthode si la collection a supprimé ne contient pas des centaines d'objets.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Merci encore pour ta réponse.

    J'ai utilisé une troisième méthode qui ressemble fortement à la deux.

    je préfère éviter la méthode 1 car ça m'obligerait ensuite à mettre à jour chaque propriété du Client du context en prenant les propriété du Client reçu par WCF. C'est assez lourd je trouve. Je préfère ré-attacher mon objet directement au context.

    En gros, j'ai rajouté une propriété à mon objet Client de type List<int> contenant les ID des Types qui seront conservées aprés modif de l'utilisateur.

    Quand je reçois le tout côté Service, j'attache mon client au context et ensuite, je compare simplement sa liste de Type (telle qu'elle était à l'origine) avec la liste contenant les ID à conserver. Selon les cas, je supprime ou j'ajoute les éléments de sa liste de Type.

    Après quelques essais, ça semble fonctionner.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2010] Impossible de créer des relations avec une table liée à Outlook
    Par lagratteCchouette dans le forum Modélisation
    Réponses: 4
    Dernier message: 26/01/2014, 21h44
  2. Réponses: 1
    Dernier message: 13/07/2012, 16h29
  3. PROBLEME AVEC UNE TABLE INTERBASE
    Par barro dans le forum InterBase
    Réponses: 1
    Dernier message: 22/09/2004, 08h16
  4. TDBChart et liaison logicielle avec une table ?
    Par Mailgifson dans le forum C++Builder
    Réponses: 10
    Dernier message: 27/07/2004, 14h11
  5. Probleme avec une table vide
    Par king dans le forum Bases de données
    Réponses: 5
    Dernier message: 20/03/2004, 14h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo