Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Matthieu MEZIL

I love .Net

Abonnements

EF et WPF : Réponse à Thomas

Comme ce que je vais dire est quelque chose de fondamental si vous voulez utiliser l'EF, j'ai décidé de faire un nouveau post pour répondre à Thomas.

Pourquoi il n'est pas possible d'utiliser directement

odp.ObjectInstance = new ObservableCollection<Category>(Context.Instance.Categories);

Que ce passe-t-il quand on fait Context.Instance.Categories ?

Une requête est générée en base pour connaître les catégories. Ensuite (sauf dans le cas d'un MergeOption.NoTracking), l'EF va comparer les EntityKeys des catégories déjà présentes dans l'ObjectContext avec le résultat de la requête pour ne pas avoir à réinstancier les catégories déjà présentes. Cependant, ce qui est très important, c'est que les entités renvoyées devront toutes correspondre à un row dans la BD. C'est à dire que si vous ajoutez une nouvelle catégorie, elle ne sera jamais retournée tant que vous n'aurez pas persisté votre contexte en base avec la méthode SaveChanges. A l'inverse, si vous supprimez une catégorie, elle continuera d'être retournée tant que vous n'aurez pas persisté le contexte.

Ce scénario n'est pas idéal dans notre cas.

De plus, la solution tentée par Thomas pose également un autre problème. Comment l'ajout d'une catégorie va-t-elle faire rafraîchir l'UI (en l'occurrence la combo) ?

En effet, il y a deux possibilités : soit quand on ajoute une catégorie, on l'ajoute à l'ObservableCollection mais alors elle ne sera pas présente dans le contexte et implique donc du code pour la sauvegarder en base, soit on l'ajoute normalement au contexte mais dans ce cas, il va falloir manuellement déclencher l'évènement CollectionChanged après le SaveChanges.

Bref, vous l'aurez compris, le passage par ObservableCollection n'est, à mon avis, pas idéal dans notre cas.

Maintenant j'aimerais revenir sur ma solution. L'avantage de passer par l'ObjectStateManager va vous permettre de

  1. Ne pas avoir à exécuter une nouvelle requête en base dès que vous voulez ajouter / supprimer une catégorie
  2. Pouvoir récupérer les catégories sans avoir besoin pour cela de les persister en base.
  3. Ne pas avoir à partager l'ObservableCollection entre les différentes fenêtres de l'application car pour ajouter une catégorie, il suffira de faire

         NorthwindEntities.Instance.AddToCategories(new Category { bla bla bla });

         avec bla bla bla les propriétés de Category que vous souhaitez initialiser.

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Publié samedi 30 août 2008 12:49 par Matthieu MEZIL

Classé sous : , , ,

Commentaires

# re: EF et WPF : Réponse à Thomas @ samedi 30 août 2008 13:35

En même temps, si l'on part sur mon idée, l'ajout d'un produit/employee dans la base/IHM se fait tout simplement;

private void btnAdd_Click(object sender, RoutedEventArgs e)

       {

           Employees employee = new Employees(){ EmployeeID = 12345, LastName = "LEBRUN" };

           ctx.AddToEmployees(employee);

           ((ObservableCollection<Employees>)this.lb.DataContext).Add(employee);

           //this.ctx.SaveChanges();

       }

Certes, cela nécessite du code en plus car il faut ajouter l'élément à l'IHM et au Context mais en même temps, cela permet d'avoir accès, à tout moment à l'élément ajouté :)

Bref, je dirais qu'il y a du pour et du contre dans chacune des méthodes: t'en penses quoi ? ;)

Thomas LEBRUN

# re: EF et WPF : Réponse à Thomas @ samedi 30 août 2008 13:59

Why not mais ça t'oblige à partager ton ObservaleCollection dans toutes ton UI pour l'utiliser comme source de ta combo, dans le cas d'un Add, dand le cas d'un Delete et dans le cas où tu déciderais d'annuler toutes les modifs en cours.

De plus, ma classe ContextEntitiesLoaded gère le tri contrairement (sauf erreur de ma part) à ObservableCollection.

Mais sinon oui ta solution est possible.

Matthieu MEZIL

# re: EF et WPF : Réponse à Thomas @ samedi 30 août 2008 14:18

&gt;&gt; Why not mais ça t'oblige à partager ton ObservaleCollection dans toutes ton UI

C'est pour ca qu'en WPF, on a la possibilité de mettre ds ressources dans le fichier App.xaml: tout ce qui est dans ce fichier est partagé par toute l'IHM (ie: toutes les fenêtres, UC, etc...) de ton application

&gt;&gt; De plus, ma classe ContextEntitiesLoaded gère le tri contrairement (sauf erreur de ma part) à ObservableCollection.

Bah, ObservableCollection une collection donc tu as accès aux méthodes d'extension associées (OrderBy, GroupBy, etc.). Et, au pire, tu peux utiliser une CollectionView, comme c'est recommandé en WPF (http://www.beacosta.com/blog/?cat=13) :)

Thomas LEBRUN

# re: EF et WPF : Réponse à Thomas @ samedi 30 août 2008 16:27

Pour le coup je suis d'accord avec Thomas. Ca me parrait super mal de me binder directement au contexte EF.

Et comme il dit, le tri / filtre / groupement sur une collection locale se fait à base de CollectionView en WPF.

Encore une fois, me binder directement à des objets de la couche Persistance, ca me fait mal au coeur

simon ferquel

# re: EF et WPF : Réponse à Thomas @ samedi 30 août 2008 19:27

"C'est pour ca qu'en WPF, on a la possibilité de mettre ds ressources dans le fichier App.xaml: tout ce qui est dans ce fichier est partagé par toute l'IHM (ie: toutes les fenêtres, UC, etc...) de ton application"

Oui et non, imagine que tu es une méthode dans ta BLL : ClearCategoriesEmpty qui supprime les catégories sans produits. Dans ce cas, comment feras-tu ? Tu peux bien sûr définir ton ObservableCollection dans la BLL ou utiliser des délégués mais bon...

Matthieu MEZIL

# re: EF et WPF : Réponse à Thomas @ samedi 30 août 2008 19:46

Juste pour rappel, je n'ai jamais fait de WPF donc il est fort possible que ce que je propose ne soit pas la meilleure solution.

Simon,

Je suis d'accord avec toi mais ceci était plus un prototype. Pour bien faire il faudrait passer par une interface plutôt que de passer directement l'ObjectContext (cela est aussi valable pour la solution de Thomas) afin d'être indépendant de l'accès aux données. Juste une petite remarque, dans mon cas, la classe ContextEntitiesLoaded ne doit pas faire partie de la couche UI même si l'EF apporte une couche d'abstraction suppélementaire qui permet d'être plus souple vis à vis de ce genre de contrainte.

Matthieu MEZIL

# re: EF et WPF : Réponse à Thomas @ dimanche 31 août 2008 23:35

Matthieu, la classe ContextEntitiesLoaded que tu as créée s'appelle communément une "vue".

Comme tu dis ce n'est qu'un proto. En général, pour avoir une architecture plus propre et limiter les dépendances, on sépare ta classe en deux classes, un controleur et la vue.

En WPF, qu'on le veuille ou non, il y a déjà un mécanisme de vue automatique associé à chaque binding.

Le plus propre que tu pourrais faire, en respect de l'architecture de WPF serait de dériver la classe CollectionView en la spécialisant pour EF.

Il faudra ensuite créer cette vue explicitement au moment du binding.

Mitsu

# re: EF et WPF : Réponse à Thomas @ lundi 1 septembre 2008 09:21

Thomas, Simon et Mitsu, merci pour vos conseils. Quand je trouverais un peu de temps (je crois que j'ai une journée de libre vers 2012 lol), j'essaierai tout ça.

Matthieu MEZIL

# re: EF et WPF : Réponse à Thomas @ lundi 1 septembre 2008 18:44

Merci à tous d'avoir participé à cette discussion fort constructive pour moi. Je suis heureux et étonné que ma question à Matthieu ait soulevé un tel débat et encore plus avec de tel expert. J'espère en tous cas avoir un peu de temps pour mettre en oeuvre vos différentes solutions.

nhooge

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- [Refactoring] ReSharper pour Visual Studio 2010 (Preview) par Thomas Jaskula le il y a 2 heures et 53 minutes

- [Refactoring] Analyser vos exceptions avec ReSharper Exceptional par Thomas Jaskula le il y a 4 heures et 7 minutes

- SharePoint 2007 : patterns & practices SharePoint Guidance par Philippe Sentenac [MVP SharePoint] le il y a 17 heures et 46 minutes

- [Visual Studio 2010] Les tests cases c’est bien, mais je vais devoir tout réécrire ? par Etienne Margraff le il y a 18 heures et 43 minutes

- MVP[Gribouillon].AddYear par The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le il y a 18 heures et 58 minutes

- Clinique INSIA - Projet de fin d’Etudes (Silverlight 3 MVVM et OutOfBrowser, WCF, TFS) - Part 1 par David REI le 07-02-2009, 23:38

- C’est la crise ? Bah pourquoi cramer du budget pub alors ? par Nix's Blog le 07-02-2009, 15:31

- Soyons MVP ! par TheSaib .NET blog le 07-02-2009, 12:15

- SharePoint : Gestion des Erreurs 6398, 7076 et 6482 par Blog Technique de Romelard Fabrice le 07-02-2009, 11:53

- EF avec WPF par Matthieu MEZIL le 07-02-2009, 10:18