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

Framework .NET Discussion :

[Entity Framework] Insert avec clé étrangère


Sujet :

Framework .NET

  1. #1
    Rédacteur
    Avatar de Yoshio
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    1 732
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 732
    Par défaut [Entity Framework] Insert avec clé étrangère
    Bonjour,

    Alors, j'utilise l'Entity Framework et l'ADO.NET Data Service pour la gestion de ma db.
    Je n'arrive pas à insérer un tuple. A chaque coup il me sort une exception.

    Voici l'exception :



    Voici le schéma simplifié :



    Je suis dans un projet Silverlight. Quand je lance l'application j'initialise les champs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    this.Database = new JobHuntersExtEntities(new Uri("../WebDataService.svc", UriKind.Relative));
                this.Database.SaveChangesDefaultOptions = SaveChangesOptions.Batch;
                this.Database.MergeOption = MergeOption.AppendOnly;
    Ensuite toujours dans l'initialisation je lance un handler que j'utilise pour récupérer une variable de session venant d'un projet asp.net lié (enfin c'est pas très important ici) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    this.CompanyId = new Guid(e.Result.ToString());
     
                // Récupération de l'objet de l'entreprise
                var queryCompany = (from c in this.Database.Companies.Expand("Ads")
                                   where c.Id == this.CompanyId
                                   select c) as DataServiceQuery<Company>;
     
                queryCompany.BeginExecute(
                    (ar) => this.Company = queryCompany.EndExecute(ar).First<Company>(),
                    null);
    La valeur de this.Company est bien différente de null et ce à quoi je m'attends.

    Quand je clique sur le bouton de mon formulaire pour ajouter le tuple à la db :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    private void UiButtonSubmit_Click(object sender, RoutedEventArgs e)
            {
                // Date de publication
                DateTime publication;
                if (this._uiDatePickerPublication.SelectedDate == null)
                    publication = DateTime.Now;
                else
                    publication = (DateTime)this._uiDatePickerPublication.SelectedDate;
                
                // Ajout de l'annonce
                Ads ad = new Ads();
                ad.Title = this._uiTextBoxTitle.Text;
                ad.Description = this._uiTextBoxDescription.Text;
                ad.DateCreation = DateTime.Now;
                ad.DatePublication = publication;
                ad.Validity = Int16.Parse(this._uiComboBoxValidity.SelectionBoxItem.ToString());
                ad.Salary = Decimal.Parse(this._uiSalary.Text);
                ad.ContractType = (ContractType)this._uiComboBoxType.SelectedItem;
                ad.Company = this.Company;
                this.Database.AddToAds(ad);
                this.Database.AddLink(ad, "Company", this.Company);
                
                this.Database.BeginSaveChanges(SaveChangesOptions.Batch, (asyncResult) =>
                {
                    try
                    {
                        this.Database.EndSaveChanges(asyncResult);
                        MessageBox.Show("Ok");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.InnerException.Message);
                    }
                }, null);
    
            }
    L'exception est lancée dans le BeginSaveChanges.

    J'ai essayé sans et avec le this.Database.AddLink(ad, "Company", this.Company); mais le résultat est le même, il me balance l'exception.


    Est ce que quelqu'un sait comment faire ? Surement un problème avec l'objet this.Company qui n'a pas les bonne référence mais je ne vois pas comment faire autrement.


    Yoshio.

  2. #2
    Rédacteur
    Avatar de Yoshio
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    1 732
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 732
    Par défaut
    Personne n'a une idée ?

    Ca doit être assez commun comme opération pourtant.

  3. #3
    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
    Et si tu ajoutes ton Ads depuis ta company :

    Company.Ads.add(tonads) et que tu save Company plutôt que Ads ?

  4. #4
    Rédacteur
    Avatar de Yoshio
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    1 732
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 732
    Par défaut
    J'ai plus d'exception, mais je n'ai quand même rien dans la base de donnée.

  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
    Essayes, mais regardes si j'ai bien compris la syntaxe..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
                DateTime publication;
                if (this._uiDatePickerPublication.SelectedDate == null)
                    publication = DateTime.Now;
                else
                    publication = (DateTime)this._uiDatePickerPublication.SelectedDate;
                
                // Ajout de l'annonce
                Ads ad = new Ads();
                ad.Title = this._uiTextBoxTitle.Text;
                ad.Description = this._uiTextBoxDescription.Text;
                ad.DateCreation = DateTime.Now;
                ad.DatePublication = publication;
                ad.Validity = Int16.Parse(this._uiComboBoxValidity.SelectionBoxItem.ToString());
                ad.Salary = Decimal.Parse(this._uiSalary.Text);
                ad.ContractType = (ContractType)this._uiComboBoxType.SelectedItem;
                this.Company.Ads.Add(ad)
                /*this.Database.AddToAds(ad);
                C'est normalement inutile de l'attacher au context, vu que tu l'attaches à une entité existante : company
                this.Database.AddLink(ad, "Company", this.Company);*/
                
                this.Database.BeginSaveChanges(SaveChangesOptions.None, (asyncResult) =>
                {
                    try
                    {
                        this.Database.EndSaveChanges(asyncResult);
                        MessageBox.Show("Ok");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.InnerException.Message);
                    }
                }, null);

  6. #6
    Rédacteur
    Avatar de Yoshio
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    1 732
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 732
    Par défaut
    Même erreur.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 12
    Par défaut
    Bonsoir,

    Je ne suis pas expert en la matière, mais vu que le problème ne semble pas résolu, je me lance :

    Je reprendrais le code précédent, en changeant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.Company.Ads.Add(ad);
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ad.CompanyReference.EntityKey = this.Company.EntityKey;
    this.Database.AddToAds(ad);

  8. #8
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut
    c'est pas "SetLink" plutôt que "AddLink" ?

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 7
    Par défaut
    je débute en EF et .NET, mais je n'ai pas rencontrer ce problème:

    j'ai aussi des tables primaires qui ont des foreign keys.

    Par contre je travail avec le modèle objet EDM plutôt que Link to SQL ou Link to Entity:

    Exemple, j'ai une table Projects (clef primaires ProjectId) avec une table Scènes qui à une clef étrangère ProjectId, etc..

    Cet extrait de code n'est pas complet.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    MGS2LocalDatabaseEntities LDEntityFramework = new MGS2LocalDatabaseEntities();
     
                Projects myProject = Projects.CreateProjects(projectId, "Projet Test" + timestamp.ToString(), Guid.NewGuid(), timestamp);
     
                // Ajout du projet dans l'entity model
                LDEntityFramework.AddToProjects(myProject);
     
     
                // Ajout de scenes dans le projet
                for (int i = 0; i < 3; ++i)
                {
                    myProject.Scenes.Add(Scenes.CreateScenes(Guid.NewGuid(), "Ma scene" + timestamp.ToString(), "", Guid.NewGuid(), ++timestamp));
                }
                // ajout d'entités dans les scenes
                foreach (Scenes s in myProject.Scenes)
                {
                    for (int i = 0; i < 3; ++i)
                    {
                        s.Entities.Add(Entities.CreateEntities(Guid.NewGuid(), "Entity Test" + timestamp.ToString(), "", Guid.NewGuid(), ++timestamp));
                    }
     
                    foreach (Entities e in s.Entities)
                    {
                        tple.Entities.Add(e);
                        e.EntityProperties.Add(EntityProperties.CreateEntityProperties(Guid.NewGuid(), Guid.NewGuid(), value, Guid.NewGuid(), 0, 0, dt, Guid.NewGuid(), ++timestamp));
                    }
                }
     
                // Ecriture des changements en database (cela forme une transaction)
                LDEntityFramework.SaveChanges(true);

    chaque fois que j'ai eu ton exception, c'est que je ne respectais pas les contraintes d'une de mes clefs étrangères, une fois fixé, ça fonctionne très bien.

    Mes clef étrangères contiennent aussi les triggers ON DELETE CASCADE chaque fois que c'est possible (pas de bouclage circulaire), pour simplifier le code de suppression.



    Pour accéder aux données j'utilise aux maximum le modèle EDM, en évitant le plus possible les appels explicite à LINK to Entity ou Link to SQL.


    Exemple de code affichant une partir du contenu de ma data base:
    (le code en commentaire correspond à différents essais).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
                // Load all project and content:
    //            List<Projects> listProject = LDEntityFramework.Projects.ToList<Projects>();
    //            List<Projects> listProject = (from p in LDEntityFramework.Projects select p).ToList();
                LDEntityFramework.Projects.Select("from p in LDEntityFramework.Projects select p");
                LDEntityFramework.Users.Select("from u in LDEntityFramework.Users select u");
                LDEntityFramework.Rights.Select("from r in LDEntityFramework.Rights select r");
                foreach(Projects p in LDEntityFramework.Projects)
                {
                    Console.WriteLine("Project: " + p.ProjectId.ToString() + " " + p.ProjectName);
     
                    // load groups, users and rights
                    p.Groups.Load();
                    foreach (Groups g in p.Groups)
                    {
                        g.UserGroups.Load();
                        g.GroupRights.Load();
                    }
     
                    // Load TemplateComponents, TemplateEntities
                    p.TemplateComponents.Load();
                    p.TemplateEntities.Load();
                    foreach (TemplateComponents tc in p.TemplateComponents)
                    {
                        Console.WriteLine("    Nombre de properties pour le composant courant: " + tc.TemplateComponentProperties.Count());
                        tc.TemplateComponentProperties.Load();
                        Console.WriteLine("    Nombre de properties pour le composant courant: " + tc.TemplateComponentProperties.Count());
                        Console.WriteLine("    Nombre de TemplateEntityComponent pour le composant courant: " + tc.TemplateEntityComponents.Count());
                        tc.TemplateEntityComponents.Load();
                        Console.WriteLine("    Nombre de TemplateEntityComponent pour le composant courant: " + tc.TemplateEntityComponents.Count());
                    }
     
                    foreach (TemplateEntities tes in p.TemplateEntities)
                    {
                        Console.WriteLine("     TemplateEntityComponent count for TemplateEntity: " + tes.TemplateEntityComponents.Count());
                    }
     
                    // load scenes, entities
                    p.Scenes.Load();
                    foreach (Scenes s in p.Scenes)
                    {
                        Console.WriteLine("    Scenes: " + s.SceneId.ToString() + " " + s.SceneName + " ");
                        s.Entities.Load();
                        foreach (Entities e in s.Entities)
                        {
                            e.EntityProperties.Load();
                            Console.WriteLine("        Entity: " + e.EntityId.ToString() + " " + e.EntityName);
                        }
                    }
                }

Discussions similaires

  1. [Optimisation] Insert avec Entity Framework
    Par Er3van dans le forum Entity Framework
    Réponses: 12
    Dernier message: 12/05/2011, 13h03
  2. [Entity Framework] Problème avec le Designer
    Par farfadet dans le forum Framework .NET
    Réponses: 16
    Dernier message: 18/02/2010, 13h13
  3. [Entity Framework] Insertion de donnée avec LINQ to Entities
    Par Leelith dans le forum Framework .NET
    Réponses: 15
    Dernier message: 05/11/2009, 22h56
  4. Réponses: 2
    Dernier message: 06/04/2009, 15h40
  5. Insert avec zend framework
    Par rugby_roux dans le forum Zend
    Réponses: 1
    Dernier message: 30/01/2007, 17h22

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