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

Entity Framework Discussion :

[EF4] POCO et pattern


Sujet :

Entity Framework

  1. #1
    Membre Expert

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Par défaut [EF4] POCO et pattern
    Bonjour,

    Je découvres les nouveautés d'Entity Framework 4 et une des implémentations qui m'a le plus convaincu avec les POCO et celle qui utilises des Repository et Unit Of Work. Voici un représentation simple :

    Une couche Infrastructure, dans laquelle on trouve : Repository, Unit Of Work et EDMX
    Une couche Service
    Une couche domaine
    Et une couche de présentation WPF

    Mais elles ont amenées leurs lots d’interrogations :

    - Unit Of Work est un objet d'infrastructure, comme l'est Repository, mais son utilisation est elle limitée dans la couche Service ? Ou peut on l'utiliser au niveau des couches supérieures (présentation) ?

    - La gestion de la MAJ des objets POCO, si on conserve le context côté client avec l'utilisation d'un UOW, c'est assez simple, mais si on perd le context, il faut soit rattacher l'objet, soit reporter les modifications dans un objet connecté, mais chacune de ces solutions ne me semble pas totalement satisfaisante. Qu'en est il pour vous ?

    D'avance merci pour toutes sources, articles ou suggestions qui peuvent faire avancer mon schmilblick
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  2. #2
    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
    Bonsoir,

    C'est intéressant (et rare) un sujet parlant d'architecture autour d'EF, je vais donc te partager mon expérience (2 ans et demi d'EF).

    Au début je faisais une couche UnitOfWork, par son approche cette classe est accessible partout mais dans les faits je ne pense pas que c'est une bonne idée de s'en servir dans le plus haut niveau de l'architecture.
    En Asp.net MVC controler/Service/Repository
    En Asp.net avec MVP : Presenter/Service/Repository
    En Asp.net "sans archi" : Code behind/Service/Repository
    Perso je n'utilise plus l'approche UnitOfWork, j'utilise à la place l'injection de dépendance avec Microsoft Unity.

    Cette gestion de MAJ des objets EF est un probleme vaste avec beaucoup d'approches possibles...
    Perso j'identifie 2 cas :

    - Un mode complètement connecté : une application ou la modification des objets est toujours connecté à un ObjectContext (en général une appli web ou une WPF qui tape directement dans la base de données).
    Dans ce cas la le data context est toujours vivant et il n'y a aucune notions d'attach ou detach. Le context est créé dans le cadre d'une application web pour chaque requête.
    - un mode déconnecté (webservice) : dans ce cas la j'utilise des poco avec des propriétés intégrants les cléfs étrangères, les update sont fait par des méthode dédié à chaque objets (avec un attach en mode modifié).
    Les relation n à n sans entités intermédiaires sont interdites.

    Si tu as d'autre question n'hésite pas

  3. #3
    Membre Expert

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Par défaut
    Merci pour ton retour d'expérience

    En mode complètement connecté, tu n'utilises pas les POCO ?
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  4. #4
    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
    Dans tous les cas j'utilise les POCO.

    Par contre en mode connecté j'active toujours le mode proxy, en mode déconnecté ça dépend...

  5. #5
    Membre Expert

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Par défaut
    Ta solution connectée correspond à ce que j'essaie de faire, sauf que moi pour la gestion du context et le garder actif (dans le cadre d'une application WPF) j'utilises Unit Of Work, de ce que je comprends toi tu injectes dans tes repository le context, donc comment fais tu pour la garder tout au long de la vie de ton objet ?
    Supposant que tu utilises WPF avec une architecture MVVM, tu associerais ton context à travers le repository à une VM ?

    Encore merci
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  6. #6
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Citation Envoyé par rad_hass Voir le message
    Ta solution connectée correspond à ce que j'essaie de faire, sauf que moi pour la gestion du context et le garder actif (dans le cadre d'une application WPF) j'utilises Unit Of Work, de ce que je comprends toi tu injectes dans tes repository le context, donc comment fais tu pour la garder tout au long de la vie de ton objet ?
    Supposant que tu utilises WPF avec une architecture MVVM, tu associerais ton context à travers le repository à une VM ?

    Encore merci
    D'après ce que je comprends, son context est transversal et géré par le conteneur d'injection de dépendances

  7. #7
    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
    Pour moi pas d'entité connecté a un objectContext EF dans WPF ... Ça pose quelques problèmes ...

    Sinon la solution que j'utilise est dans mon framework (petit coup de pub discret ) mais par contre en mode connecté c'est pour de l'asp.net , c'est un LifetimeManager Unity :

    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
        public class PerRequestLifetimeManager<T> : LifetimeManager, IDisposable
        {
            public override object GetValue()
            {
                return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
            }
     
            public override void RemoveValue()
            {
                HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
            }
     
            public override void SetValue(object newValue)
            {
                HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
            }
     
            public void Dispose()
            {
                RemoveValue();
            }
        }
    Pour du WPF sans webservice pour moi c'est assez sujet à débat ... Je pourrais te donner des pistes mais mes applications WPF recente ont des WS ...

    J'ai vu un collègue galérer avec des entités (POCO proxifié) connectés à l'object context bindé directement dans l interface.

    Moi j'en visagerai ces pistes là :

    - Utiliser un autre modèle objet utilisé dans l'UI (un peu lourd)

    - Ou alors mieux un systeme dans ce style là :
    Une couche "Model" contenant les POCO
    Une couche "MVVM" avec un ViewModel et View
    Une couche "Service"
    Une couche "Repository" (data access)

    La partie ViewModel ne ferrait des appels a la partie service que par un systeme de background worker (ou autre), donc en gros le VM et V serait dans le thread de l'UI pendant que la partie service tournerait dans d'autres threads.
    L'objectcontext serait en mode 1 Objectcontext par thread (il y a un conteneur comme ca dans unity) et donc l'injecteur de dépendance injecterait le même objectcontext dans tous les repository utilisé pendant une "interaction utilisateur"

    Et entre la couche service et VM les objet passant d'un monde a l autre serait attaché puis détaché puir rattaché de sorte que les entité dans "le monde UI" ne soit jamais lié à l'object contexte (au final cela ressemble au passage a une couche de service distant)

    Bref c'est un brouillon de concept, pas une solution mais personnellement je partirai dans quelque chose dans ce style la

    Je sais pas si je suis très clair

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Par défaut
    Merci pour cette réponse détaillé

    Pour moi pas d'entité connecté a un objectContext EF dans WPF ... Ça pose quelques problèmes ...
    Lesquels des problèmes ?

    Une couche "Model" contenant les POCO
    Une couche "MVVM" avec un ViewModel et View
    Une couche "Service"
    Une couche "Repository" (data access)
    C'est à peu près ce système que j'ai mis en place... Par contre pour l'instant, je suis sur une solution connecté, mais ça me plaisait pas trop d'avoir le context au niveau de l'UI, mais bon la solution attaché/détaché ne me plaisait pas non plus des masses pour les updates... Du coup j'essai de voir les meilleures implémentations. Et peut être que les problèmes que t'as rencontré avec le mode connecté peuvent mieux m'éclairer

    Encore merci
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  9. #9
    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 un collègue qui a eu pas mal de merde la dessus, il venait me poser des questions pour les résoudre. Et a chaque fois ça finissait par "je t'avais dis de pas mettre d'objets connectés à EF dans l'UI"

    Je cite un exemple :


    J'en ai marre de tomber sur toutes les merdes d'EF !!!!!
    Je me suis abonnée à propertychanged sur une entité et lorsqu'une des propriétés est modifée je dois recalculer un score mais ça pète une exception.
    A priori on ne doit pas modifier une autre entité dans un propertychanged.... Ce serait un bug EF avec les POCO que plein de gens rencontrent. J'en ai marreeee. Tu aurais pas une petite solution ??????????????????

    sèb.

    Message=EntityMemberChanged or EntityComplexMemberChanged was called without first calling EntityMemberChanging or EntityComplexMemberChanging on the same change tracker with the same property name. For information about properly reporting changes, see the Entity Framework documentation.
    Et non il n'y avait pas de solution super propre à son problème sans changer l'architecture, aussi basique que puisse être le probleme

    Vis a vis de se dire "je ne ferrais jamais d'attach et de detach", ce n'est que repousser quelque chose dont tu auras forcement besoin un jour.
    Si tu dois sérialiser tes entités (que ce soit pour les stocker dans un fichier ou les envoyer par un Web service) tu auras besoin d'utiliser et maîtriser cette notion qui n'est franchement pas méchante.

    Il y a aussi le problème de sauvegarde des modification par écrans ... Si tu as plusieurs écran ouvert sur le meme object context et que tu veux sauvegarder sur un écran ca sauvegarde partout ! Si tu as un object context par ecran tu empêche tes objets de se balader d'un écran à l'autre (ou alors ta couche UI fait des Attach et Detach, super !).
    Tu n'as pas ce genre de problème avec des objets découplés de l'object context, tu updates seulement ceux que tu veux et tu les balades comme tu veux.

    Apres si tu veux garder un tracking efficient tu peux utiliser des self tracking entities ou mettre en place un système où tu conserve l'entité original et utilise l'original et la modifié pour faire tes update

    Ce ne sont que des exemples, les petits trucs comme ça, il y en a un paquet ... Apres si tu veux te faire ta propre expérience, libre à toi, on progresse aussi avec des erreurs

  10. #10
    Membre Expert

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Par défaut
    J'entends bien ce que tu me dis, mais ce que je cherchais à savoir c'est les raisons qui me pousserait à faire ce choix, selon les besoins de l'application que je mets en place. Et ce que je comprends de ton propos, c'est qu'il y a des retours d'expériences relatant les difficultés à mettre en oeuvre cette solution...

    Dans l'idéal effectivement ça serai que je mette en oeuvre les deux solutions pour les comparer, mais l'idéal n'est pas toujours possible, c'est pour cette raison que les retours d'expériences sont forts utiles pour éviter les erreurs courantes.

    Encore merci pour ton retour
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  11. #11
    Membre Expert

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Par défaut
    Sinon Anthyme comment gères tu l'attach/detach, dans tes applications ? J'ai trouvé plusieurs façon de le faire pour un Update par exemple :

    Y en qui surcharges les objets.
    Y en a qui récupère l'objets en base et copie les modifications avant de sauver (pas du tout convaincu par cette solution).

    Y a t il un mécanisme particulier que tu utilises ?
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  12. #12
    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
    Ca dépend du contexte à vrai dire.

    Sur une appli comme la tienne je pense qu'il faudrait un système qui copie l objet et conserve l original puis applique les modif de l original a la copie.

    Dans un contexte de webservice j'ai fait ceci :

    http://arch.codeplex.com/SourceContr.../82373#1500856

    Pour le moment la méthode Load fait un getbyID mais le but est a terme de crer un ghost (instance contenant juste l'id) proxifié et attaché au contexte et faire les update dessus. Comme cela pas d'appel supplémentaire en base.

    Cela fonctionne bien avec nhibernate mais pas eu le temps de creuser beaucoup plus sur EF.

    Peut être en faisant un createobject sur le contexte EF puis detach de l'objet puis on affect l'Id, on reattach et on obtiendrait un Ghost proxifié lié au contexte.
    Il n'y aurai plus qu'a appliquer les mise à jour (comme dans mon code).

    Pour info ette clase est fait un peu à l'arrache
    J'attend de trouver une vrai bonne solution (et d’ailleurs je ne fais plus comme ça pour les navigation property)

Discussions similaires

  1. EF4 avec T4 template POCO Entity Generator
    Par Florian.L dans le forum Entity Framework
    Réponses: 9
    Dernier message: 30/08/2010, 16h18
  2. Réponses: 4
    Dernier message: 24/02/2009, 12h06
  3. Interfaces, Pattern Observer
    Par IProg dans le forum Langage
    Réponses: 8
    Dernier message: 18/12/2003, 14h11
  4. [Design Patterns] Architecture 3 tiers
    Par HPJ dans le forum Design Patterns
    Réponses: 1
    Dernier message: 29/07/2003, 11h49
  5. [langage] expression reguliere motif répétitif dans 1 pattern
    Par comme de bien entendu dans le forum Langage
    Réponses: 11
    Dernier message: 09/04/2003, 16h14

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