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

Accès aux données Discussion :

The relationship between the two objects cannot be defined because they are attached to different ObjectContex


Sujet :

Accès aux données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 93
    Par défaut The relationship between the two objects cannot be defined because they are attached to different ObjectContex
    Bonjour,
    Je souhaite ajouter une relation entre deux objets d'une base de données en EDMX.
    Mon problème semble relativement simple :

    J'ai un premier objet chargé ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    BD = new MonModeleEDMX();
    ObjetTable1 = from l in BD.Table1
                        where l.IdT1 == IdT1)
                        select l;
    Puis un autre objet chargé dans une autre fonction ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    BD = new MonModeleEDMX();
    ObjetTable2 = from l in BD.Table2
                        where l.IdT2 == IdT2)
                        select l;
    Il existe une table d'association (relation NN) entre Table1 et Table2.
    Je souhaite donc créer une nouvelle association entre ces deux objets.
    J'ai essayé ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ObjetTable1.Table2.Add(ObjetTable2);
    mais j'obtiens le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
    Puis ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ObjetTable2.BD.Detach(ObjetTable1);
    --> The object cannot be detached because it is not attached to the ObjectStateManager.
     
    ObjetTable1.BD.AttachTo(ObjetTable2.IdT2.ToString(), ObjetTable2);
    --> The EntitySet name 'GestionAssociationEntities.13' could not be found.
    J'avoue ne pas trop comprendre ni ce qui se passe ni ce que je dois faire.

    Merci d'avance.

  2. #2
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 273
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 273
    Par défaut
    Tu as créé deux contextes donc c'est assez logiques que pour des motifs d'états et de concurrence un contexte ne puisse pas modifier ou agir sur les entités attachées à un autre objet.




    Expose ton context via un singleton et tu devrais vite voir le résultat changer.
    Le pb est là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    BD = new MonModeleEDMX();
    Tu verras d'ailleurs que soit tu utilises :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    BD = new MonModeleEDMX();
    ObjetTable1 = from l in BD.Table1
                        where l.IdT1 == IdT1)
                        select l;
    ObjetTable2 = from l in BD.Table2
                        where l.IdT2 == IdT2)
                        select l;
    ObjetTable1.Table2.Add(ObjetTable2);
    Ton pb va disparaitre.

    Il s'agit là de comprendre un autre pattern important à l'ORM : Unit of Work

    Là.

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 93
    Par défaut
    Merci pour la réponse,
    Je pense que mon problème vient clairement d'un problème quant à l'utilisation du contexte.

    En fait mes deux objets Table1 et Table2 ne sont pas gérés au même niveau, ce qui explique pourquoi je ne les ai pas chargé avec le même contexte.

    J'avais volontairement simplifié un peu le problème.
    En réalité je charge une liste d'objets de Table2 via un Web service.
    Puis via l'application l'utilisateur sélectionne un élément de la liste.

    C'est pour cette raison que je souhaitais enlever l'objet Table2 de son contexte pour l'ajouter au contexte de Table1.

    Mais j'ai peut-être une autre solution qui est de passer en paramètre mon contexte (MonModeleEDMX) en paramètre à mon Web Service.
    En fait, je ne sais pas exactement à quel niveau je dois gérer mon contexte. Est-ce au niveau des objets ou au niveau de la page web ?
    Ou alors je me trompe complètement.

    Merci d'avance.

  4. #4
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 93
    Par défaut
    Que pensez-vous notamment du fait de mettre le contexte (MonModeleEDMX()) directement en session ?
    Si c'est mal, en quoi est-ce mal ?

  5. #5
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 273
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 273
    Par défaut
    En session de quoi ?

    WCF ? ASP.Net ?

    Moi je crois qu'EF doit être utilisé avec des services et chaque service doit réaliser sa propre transaction. Pour le moment, ça me parait compliqué de gérer des conversations.

    Ce qui est mal d'une façon générale c'est de faire des sessions longues, quelque soit l'ORM : cela peut poser des problèmes en légion.
    Il faut donc faire court prècis, et dans la majeure partie des cas utiliser les transactions et le Using pour disposer correctement.

  6. #6
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 93
    Par défaut
    Je suis en ASP.Net,

    La liste des objets de la Table2 est utilisée pour remplir un GridView.
    Elle est concervée en mémoire comme DataSource du GridView sur lequel je peux faire des actions qui vont "taguer" les objets de la liste. Il serait peut-être déjà bien à ce niveau de fermer le contexte de la liste qui de toute façon n'est là que pour de l'affichage. Dois-je faire un Dispose ou autre chose ?

    Puis l'utilisateur valide le formulaire et là tous les objets "tagués" de la liste vont être ajoutés à la liste des objets Table2 rattachés à l'objet de la Table1.

    Entre temps il y a bien entendu eu plusieurs postback.

    Actuellement dans mon code j'ouvre le contexte au chargement d'un objet ou d'une liste que je ne ferme jamais car je n'avais pas encore pris le temps de me poser la question du quand et du comment.

    J'ai donc un contexte au chargement de la liste Table2 et un contexte au chargement de l'objet Table1.
    Entre temps l'utilisateur va faire plusieurs postback, puis faire sa validation.
    Ayant toujours les contextes (depuis sans doute trop longtemps déjà), j'ai juste à faire ma sauvegarde, mais arrive le problème évoqué.

    Et ça m'embeterait de devoir recharger les objets Table2 juste pour les ajouter à Table1 sachant que je les ai déjà en mémoire.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/07/2010, 09h04
  2. Réponses: 1
    Dernier message: 22/04/2010, 12h24
  3. Réponses: 3
    Dernier message: 10/08/2009, 15h14
  4. Réponses: 9
    Dernier message: 19/11/2008, 08h17
  5. Réponses: 15
    Dernier message: 22/07/2008, 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