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 :

DatabaseToEntity et DTO


Sujet :

Entity Framework

  1. #1
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut DatabaseToEntity et DTO
    Bonjour,

    J'ai une question... qui peut paraître bête, je sais que c'est possible mais je bloque un peu...

    J'ai importer ma base de données dans EntityFramework, il m'a créer tout bien comme il faut. (dans ma DAL donc)

    J'ai ensuite créer un projet DTO transverse pour passer des objets dans toutes mes couches... Avec un script T4T pour créer pour chaque entité, une classe DTO.
    Et ça marche nickel... J'ai toutes mes classes "coquilles".


    Sauf que je bloque sur un truc....

    Quand j'écris une "requête" sur mon modèle dans ma DAL, ça me retourne évidemment un objet de type DAL.MonObjet...

    Mais comment le caster, ou comment faire pour que la requete me retourne un type DTO.MonObjet...

    Je sais que c'est possible, je l'ai déjà vu. Peut être que j'ai pas la bonne méthode...

    Merci d'avance.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  2. #2
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Je pense que pour ca il faut utiliser un mapper, comme par exemple AutoMapper. Ensuite il te suffit de mapper ton DTO avec ton Entite :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    Mapper.CreateMap<Entite, EntiteDTO>();
    Ensuite tu modifies ta DAL comme suit :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public IEnumerable<EntiteDTO> GetEntite()
    {
        using (var db = new MyContext())
        {
            return (from x in db.Entite
                    orderby x.PropertyA
                    select Mapper.Map(x)).AsEnumerable();
        }
    }
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Effectivement c'est la solution boite noire bien efficace, mais tout simplement il s'agit de transformer a la main un objet dans un autre, donc copie champs à champs. Comme c'est super chiant il y a des outils comme AutoMapper qui font le travail de manière générique.

    Apres selon le projet faut faire attention à ne pas tout vouloir transformer en DTO, si tu as beaucoup d'objet tu perds forcement en performance.

  4. #4
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Ah cool !!

    Merci les gars
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  5. #5
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Citation Envoyé par DotNetMatt Voir le message
    Je pense que pour ca il faut utiliser un mapper, comme par exemple AutoMapper. Ensuite il te suffit de mapper ton DTO avec ton Entite :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    Mapper.CreateMap<Entite, EntiteDTO>();
    Ensuite tu modifies ta DAL comme suit :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public IEnumerable<EntiteDTO> GetEntite()
    {
        using (var db = new MyContext())
        {
            return (from x in db.Entite
                    orderby x.PropertyA
                    select Mapper.Map(x)).AsEnumerable();
        }
    }

    Bonjour...

    Le code que tu m'as donné, je le retrouve dans le Getting Started de l'outil.
    Mais je vois pas bien comment ça marche...

    J'ai bien NuGet d'installé,
    Puis j'ai tapé PM> Install-Package AutoMapper
    Dans le gestionnaire de package...

    Mais après, il faut faire quelque chose ?

    Parce que l'intellisense, il reconnait pas Mapper comme objet clé...
    Donc je peux même pas écrire cette ligne :

    Mapper.CreateMap<Entite, EntiteDTO>();

    Mapper, il connait pas.... Et je n'ai aucune indication dans les ReadMe, le GetStarted...
    Il faut ajouter une référence ? (mais je ne trouve aucune référence de ce nom...)
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  6. #6
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Etrange, chez moi ca fonctionne nickel :
    Nom : Untitled.png
Affichages : 684
Taille : 120,6 Ko

    Par contre en installant la derniere version, j'ai note qu'il y avait pas mal de nouveautes par rapport a la version que j'ai l'habitude d'utiliser, et on dirait que la syntaxe a un peu change... Pour creer les mappings, il faut utiliser ceci :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Mapper.Initialize(conf => {
        conf.CreateMap<A, B>();
    });
    Ou encore un profil :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<A, B>();
        }
    }
    Et pour l'ajouter dans la configuration :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Mapper.Initialize(conf =>
    {
        conf.AddProfile<MappingProfile>();
    });
    A noter, il est possible de mixer des profils et des mappings "manuels" :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Mapper.Initialize(conf =>
    {
        conf.CreateMap<A, B>();
        conf.CreateMap<C, D>();
        conf.AddProfile<MappingProfile1>();
        conf.AddProfile<MappingProfile2>();
    });
    Si tu ne vois pas la classe Mapper, essaie en commencant par le namespace "AutoMapper.Mapper". Ca change quelque chose ?
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  7. #7
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Au temps pour moi.... Je n'avais jamais eu l'occasion d'utiliser des NuGets, il y avait une petite astuce (que peut être tout le monde connait) :

    Il ne suffisait pas d'installer le package, il fallait aller après dans le package pour l'installer dans chaque projet :

    Nom : automapper.jpg
Affichages : 727
Taille : 144,2 Ko
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  8. #8
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Bon c'est super j'avance à grand pas... (et heureusement, je suis un peu sous pression).

    Je vous explique ce que j'ai fais, je galère un peu, je n'ai trouvé aucun exemple VB.

    Ce que j'ai compris :

    - Dans le load de mon application, j'appelle une fonction shared :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Imports AutoMapper
     
    Public Class AutoMapperConfig
     
        Public Shared Sub InitialiseMapper()
     
            Mapper.Initialize(Sub(cfg) cfg.CreateMap(Of ClassLibrary_DAL.Client, ClassLibrary_DTO.Client)())
            Mapper.Initialize(Sub(cfg) cfg.CreateMap(Of List(Of ClassLibrary_DAL.Client), List(Of ClassLibrary_DTO.Client))())
     
        End Sub
     
    End Class
    Mais je comprends pas bien pourquoi cela est nécessaire, puisque la fonction Map plus loin rappel les types...
    Donc après, j'ai testé de mapper avec la ligne suivante :

    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
     Public Function GetAllClient() As List(Of ClassLibrary_DTO.Client)
     
            Using ctx As TestEntities = New TestEntities ()
     
                Dim result_DL As New List(Of Client)
                result_DL = (From st In ctx.Client
                             Select st).ToList
     
                Dim result_DTO As New List(Of ClassLibrary_DTO.Client)
     
                result_DTO = Mapper.Map(result_DL, GetType(List(Of ClassLibrary_DAL.Client)), GetType(List(Of ClassLibrary_DTO.Client)))
     
                Return result_DTO
     
            End Using
     
        End Function

    Je n'ai aucune erreur à la compilation, ni exception à l’exécution, mais je n'ai aucun résultat...
    J'ai bien vérifier que result_DL contient les clients

    Je continu à chercher des exemples et à faire des tests, mais si ça dis quelque chose à quelqu'un, je lui en serait grandement reconnaissant.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  9. #9
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Ce qui est bizarre et pas rassurant, j'ai voulu tester avec un seul élément :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim test1 As New ClassLibrary_DTO.Client
     
    test1 = Mapper.Map(result_DL(0), GetType(ClassLibrary_DAL.Client), GetType(ClassLibrary_DTO.Client))
    Me retourne l'exception :

    Une exception non gérée du type 'AutoMapper.AutoMapperMappingException' s'est produite dans AutoMapper.dll

    Informations supplémentaires : Missing type map configuration or unsupported mapping.

    J'en déduis trois choses qui m'inquiètent :

    1 : Lors de mon premier test, la configuration était bonne
    2 : Il ne m'avait pas pour autant retourné de résultat
    3 : Pourquoi celui-ci n'a pas fonctionné, alors même que j'avais créer le mapping sur le même modèle

    Nouveau test : J'ai modifié le code comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Public Class AutoMapperConfig
     
        Public Shared Sub InitialiseMapper()
     
            'Mapper.Initialize(Sub(cfg) cfg.CreateMap(Of ClassLibrary_DAL.Cepage, ClassLibrary_DTO.Cepage)())
            Mapper.Initialize(Sub(cfg) cfg.CreateMap(Of List(Of ClassLibrary_DAL.Cepage), List(Of ClassLibrary_DTO.Cepage))())
     
        End Sub
     
    End Class
    Et là j'ai eu une exception plus explicite : en effet dans client, il y a une sous classe, qu'il dit ne pas reconnaître...
    Je vais donc ajouter ces sous classes dans la configuration, et faire des tests.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  10. #10
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Bon, le type Client, possède un champ de type ICollection.

    J'ai donc fais des tests sur une autre classe toute simple de type A :
    Contient un string, et et un type B (lui même n'est que un string).

    J'ai ajouté la config, QUE pour le type A.

    Et magie, ça fonctionne....

    Donc déjà, c'est bien j'ai réussis à le faire marché. JE continue.

    J’espère juste que les erreurs que j'ai eu au début ne sont pas liés au fait que la Classe Client, contient une ICollection.
    Parce que sinon, ça va être problématique...
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  11. #11
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Je mets en résolu, car le problème initiale a eu sa réponse...

    C'est pas mal automapper... bien que je galère un peu...

    Une classe A contient une liste de classe B, qui elle même contient une liste de Classe C.
    Rien que ça, je comprends pas trop comment le faire... Et sur internet, plein de version, tout en anglais et C#...

    Mais bon... je vais insister, ou faire mon mapping moi même... (ça ira peut être plus vite, c'est des classes simples)
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  12. #12
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Si tu as des collections, pas besoin de faire un mapping de List(Of A) vers List(Of B). Il suffit d'avoir le mapping des objets de base A et B.

    Pour reference : Lists and Arrays.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [DAO] Utilisation des DTO
    Par neuromencien dans le forum Autres
    Réponses: 8
    Dernier message: 02/10/2009, 16h15
  2. Hibernate et pattern DTO
    Par mehdi_31 dans le forum Hibernate
    Réponses: 75
    Dernier message: 07/09/2009, 11h05
  3. Binder un DTO à un datagrid
    Par LEK dans le forum ASP.NET
    Réponses: 1
    Dernier message: 05/04/2008, 10h49
  4. Architecture Hibernate DTO
    Par nono44200 dans le forum Hibernate
    Réponses: 3
    Dernier message: 03/08/2007, 14h45
  5. DTO et relations entre les tables
    Par 84mickael dans le forum JDBC
    Réponses: 1
    Dernier message: 19/03/2007, 11h58

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