Bonjour,

J'utilise VS2012 avec C# et je découvre Linq to Entities en exploitant la base exemple Chinook (version sqlite).
J'ai mis en place d'un treeview qui déroule :
Artist - Album - Track
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
 
        private void Init_treeView1()
        {
            TreeNode treeNodeRacine;
            treeNodeRacine=new TreeNode("Racine");
            treeView1.Nodes.Add(treeNodeRacine);
            var treeView1_req =
                from a in context.Artist
                orderby a.Album.Count() descending
                select a;
            foreach (var artist in treeView1_req)
            {
                TreeNode treeArtist;
                treeArtist = new TreeNode(artist.Name + " (" + artist.Album.Count() + " albums)");
                treeNodeRacine.Nodes.Add(treeArtist);
                var Albums = artist.Album.OrderByDescending(p => p.Track.Count());
                foreach (var album in Albums)
                    {
                    TreeNode treeAlbum;
                    treeAlbum = new TreeNode(album.Title + " (" + album.Track.Count() + " tracks)");
                    treeArtist.Nodes.Add(treeAlbum);
                    foreach (var track in album.Track)
                    {
                        treeAlbum.Nodes.Add(track.TrackId.ToString(),track.Name + " (" + track.Genre.Name.ToString() +" )");
                    }
                }
            }
        }
Quand j'atteins le dernier niveau (3) j'affiche le nom du "Track" dans un textBox et le Genre dans comboBox afin de pouvoir les modifier.
Pour se faire, après la sélection du Node je lie ces 2 contrôles aux éléments de l'entité correspondante :

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
 
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (treeView1.SelectedNode.Level == 3)     // on prend que les entreprises pas la structure
            {
                TRACKID = Convert.ToInt64(e.Node.Name);
                var track =
                    from b in context.Track
                    where b.TrackId == TRACKID
                    select b;
                try
                {
                    textBox3.DataBindings.Clear();
                    comboBox4.DataBindings.Clear();
                    textBox3.DataBindings.Add(new Binding("Text", track.ToList(), "Name"));
                    comboBox4.DataBindings.Add(new Binding("SelectedValue", track.ToList(), "GenreId", false, DataSourceUpdateMode.OnPropertyChanged));
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erreur \n" + ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
La datasource du comboBox a été préalablement chargée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
        private void Init_comboBox4()
        {
            var ComboBox4_req =
                from a in context.Genre
                orderby a.Name
                select a;
            comboBox4.DataSource = ComboBox4_req.ToArray();
            comboBox4.DisplayMember = "Name";
            comboBox4.ValueMember = "GenreId";
        }
Ces 2 contrôles sont englobés dans un tabPage. Quand celui-ci est validé je répercute les modifications dans la base de donnée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
        private void tabPage1_Validated(object sender, EventArgs e)
        {
            try
            {
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erreur \n" + ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Tout ce passe bien pour le textBox mais la mise à jour de la clé étrangère "GenreId" qui est couplée à la combobox ne se fait pas dans la table "Track". En fait elle n'est même pas stockée dans le modèle. Dès que je change d'enregistrement, la valeur initiale de "GenreId" se repositionne. Je cherche en vain de comprendre le phénomène afin de le corriger.
Dans l'évènement "Validating" du combobox c'est bien la valeur modifiée qui apparait, mais dans l'évènement "Validated" c'est la valeur initiale qui réapparait

Afin de contourner le problème j'ai rajouter un peu de code pour faire la mise à jour "à la main" :
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
 
        private void comboBox4_SelectedValueChanged(object sender, EventArgs e)
        {
            if (TRACKID != 0)
            {
                try
                {
                    var req =
                        from a in context.Track
                        where a.TrackId == TRACKID
                        select a;
                    req.First().GenreId = Convert.ToInt64(comboBox4.SelectedValue.ToString());
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erreur \n" + ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
Ca permet bien de conserver la valeur modifiée dans le modèle et donc de mettre à jour la base mais je trouve la méthode un peu "crade" ...
Peut-on faire mieux ou autrement ?

Merci de vos lumières.