Bonjour,

J'ai un service WCF qui est appelé par un client WPF.

Le client WPF envoie au service un objet "facture" mis a jour pour enregistrer les modifications en DB. Schéma classique InvoiceHeader 1 ---- n InvoiceDetail

il faut mettre a jour :
-Les modifications au Header
-Les modifications a chaque Detail
-Ajouter les nouveaux Details
-Supprimer les detaisl qui ne sont plus nécessaire

Cela fonctionne mais il doit y avoir un moyen plus coherant et plus propre.

J'ai également utilisé le T4 avec le Self-Tracking entity

voici le Code du Click dans le client WPF:

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 btnSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                InvoiceHeader hd = InvoiceHeader)invoiceHeaderListView.SelectedItem;
                hd.ChangeTracker.State = ObjectState.Modified;
                using (var service = new ServiceClient())
                {                   
                    string b = service.UpdateInvoice(hd);
                    MessageBox.Show(b.ToString());
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }
Le code du service :

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
51
52
 
    public string UpdateInvoice(InvoiceHeader ih)
    {
        try
        {
            using (AvgTestDBEntities ctx = new AvgTestDBEntities())
            {
                try
                {
                    //Liste des element a supprimer - y stocker tout les elements qui sont en DB et pas dans l'objet en parametre
                    //Si ils sont en DB mais pas dans l'objet en parametre cela veut dire qu'il faut les supprimer de la DB
                    List<InvoiceDetail> lstToDelete = new List<InvoiceDetail>();
                    AvgTestDBEntities ctx2 = new AvgTestDBEntities();// nouveau context, sinon conflit lors de AcceptChange
                    List<InvoiceDetail> lstToCheck = ctx2.InvoiceDetails.Where(p => p.HeaderID == ih.id).ToList();
                    foreach (var item in lstToCheck)
                    {
                        int i = ih.InvoiceDetails.Count(p => p.id == item.id);
                        if (i == 0)
                        {
                            lstToDelete.Add(item);
                        }
                    }
                    foreach (var item in lstToDelete)
                    {
                        ctx.AttachTo("InvoiceDetails",item);
                        ctx.DeleteObject(item);
                    } 
 
                    // marquer tout comme modifier pour mettre a jours toutes les prop
                    foreach (var item in ih.InvoiceDetails.Where(p => p.id != 0))
                    {                      
                       item.MarkAsModified();                       
                    }       
 
                    //appliquer les modification a la facture
                    ctx.ApplyChanges("InvoiceHeaders", ih);
 
                    //sauvegarder en DB
                    ctx.SaveChanges();
 
                    return "ok";
                }
                catch (InvalidOperationException ex)
                {
                    return ex.Message;
                }
            }
        }
        catch (Exception exc)
        {
            return exc.Message.ToString();
        }
Le code fait ce qu'on lui demande, mais c'est pas tres propre.

si vous avez des solutions, je suis preneur