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

  1. #1
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut Architecture de couche d'accès aux données (DAL) de hautes performances — partie 1. (et les DTO)
    bonjour,

    Cette discussion est destinée à recueillir vos commentaires sur l'article « Architecture de couche d'accès aux données (DAL) de hautes performances — Partie 1 » et des Data Ttransfert Object (DTO).
    Traduction de l'article « High Performance Data Access Layer Architecture Part 1 » de M. Rudy Lacovara.

    DTO, DAL, BLL… Tout le monde s'en sort ? Pas si sûr !
    Voici le premier chapitre d'un article qui vous aidera à comprendre cette architecture et ses concepts-clés.
    Dans cette première partie, nous allons nous intéresser à l'architecture globale de la DAL et l'utilisation des DTO pour transférer des données entre les différentes couches de l'application.
    Nous allons aussi voir la mise en pratique de ces concepts à l'aide d'une classe PersonDB qui contiendra l'ensemble de nos méthodes d'accès aux données permettant d'obtenir et de sauvegarder les données d'une entité « personne ».
    Cette série de trois articles décrit comment écrire une couche d'accès aux données de hautes performances.
    Lien sur les discussions des autres articles : Discussion sur la partie 2, Discussion sur la partie 3

    Bonne lecture.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  2. #2
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    J'ai quelques remarques:
    - Pourquoi passer les arguments en ref :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected static T GetSingleDTO<T>(ref SqlCommand command) where T : DTOBase
    - Pourquoi utiliser SqlConnection, SqlDataReader, etc. au lieu de IDbConnection, IDataReader, etc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (reader.HasRows) { reader.Read();
    Pourquoi ne pas directement faire

  3. #3
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Bonjour meziantou

    Merci pour tes remarques. (concerne la partie 2)

    Avant tout, je préfère rappeler qu'il s'agit d'une traduction que j'ai faite, et je ne connais donc pas forcement ce que pense l'auteur (M. Lacovara) et pourquoi il a codé ainsi.
    Mais nous pouvons bien sur réfléchir sur ce qu'il a fait et sur d'autres approches différentes. (C'est toujours intéressant, cela permet de progresser.)

    Citation Envoyé par meziantou Voir le message
    J'ai quelques remarques:
    - Pourquoi passer les arguments en ref :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected static T GetSingleDTO<T>(ref SqlCommand command) where T : DTOBase
    Ici, c'est pour ne pas faire une copie locale de command dans la méthode GetSingleDTO, ce qui me semble relativement courant.

    Citation Envoyé par meziantou Voir le message
    - Pourquoi utiliser SqlConnection, SqlDataReader, etc. au lieu de IDbConnection, IDataReader, etc.
    Je ne saurai te répondre directement.
    Personnellement, j'ai créé une bibliothéque DAL générique qui me sert pour mes nouvelles appli. J'y ai intégré les DTO, aspect qui m'intéressait. J'ai transformé la méthode GetSingleDTO pour justement ne plus avoir de paramètre de type command.
    Donc une approche avec IDbConnection, IDataReader... est, me semble-t-il, parfaitement envisageable.
    J'avoue que je ne sais pas si l'utilisation d'interface peut avoir un impact sur les performances. (Le but étant d'être performant. Donc à voir sur des lectures nombreuses avec GetDTOList)
    En tout état de cause pour avoir une réponse précise par rapport aux choix effectués par l'auteur tu peux poser la question sur son blog concernant l'article 2 : « High Performance Data Access Layer Architecture Part 2 ».

    Citation Envoyé par meziantou Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (reader.HasRows) { reader.Read();
    Pourquoi ne pas directement faire
    Pour la méthode GetSingleDTO effectivement (peut être pour une meilleure lisibilité du code, l'impact d'un test étant négligeable). Par contre dans GetDTOList c'est utile puisque l'on effectue des traitements préparant la lecture.

    Espérant avoir pu répondre en partie à tes remarques.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  4. #4
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Hello,

    C'est vrai que quand j'ai découvert ces articles, je ne m'étais pas trop posé de question à l'époque (étant un noob en POO, ça fonctionnait bien alors j'ai dit amen ).

    Maintenant, à la vue des questions soulevées par meziantou, je m'interroge également.

    Concernant le passage par référence :
    Hervé donné une piste. Maintenant, à moins d'avoir une boucle qui, pour une raison x ou y, irait exécutait un certain nombre de fois la méthode, je ne vois pas trop le problème de faire un passage par valeur.
    Je remarque aussi que dans la méthode GetSingleDTO (idem pour GetDTOList), on ferme et libère la connexion. Alors je ne sais pas vous mais perso dans mes classes DAL, ça donne quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Dim obj as DTO.MonObjet
    Using cmd as SqlCommand = CreateSpCommand("STORED_PROCEDURE_NAME")
        cmd.Parameters.Add(CreateParameter("@PRM_NAME", prm_value))
     
        obj = GetSingleDTO(Of DTO.MonObjet)(cmd)
    End Using
    Return obj
    A la destruction de l'objet command par le End Using, la connection est automatiquement fermée et libérée non ?

    Concernant les types pour les objets DB (SqlConnection, SqlCommand, etc.) :
    Pour avoir lu d'autre de ces articles, je sais que l'auteur travaille avec SQL SERVER. Je pense qu'il ne faut pas chercher plus loin. Mais voir une implémentation plus générique m'intéresserait. Je suis d'ailleurs en total désaccord avec lui quand, dans un autre article, il explique qu'il ne perd plus son temps à faire une couche DAL séparée et qu'il mixe tout dans la BLL car, après tout, changer de DB n'arrive que très rarement dans la vie d'un développeur.

    Concernant If reader.HasRows() :
    Personnellement, je préfère avoir ce test en plus. Je trouve cela plus lisible. Il ne faut pas perdre de vue que, lorsque nous programmons, ce ne sera pas forcément nous qui devront maintenir le code. Et puis ça me rappelle mes cours de méthodologie où mon prof répétait sans cesse : "Je prépare, j'utilise". Donc ici, on prépare le reader (on vérifie s'il contient des données) et on l'utilise ensuite (on lit les données qu'il contient).


    Comme l'a souligné Hervé, il n'a fait qu'une traduction. Il n'est donc pas à blâmer (personne ne l'est en fait je crois). Mais ne perdons pas de vue que l'auteur n'est pas un dieu non plus. Il est donc fort possible que ce qu'il a partagé avec nous sur son blog puisse être sujet à amélioration. Je vois plus ces articles comme une bonne base de travail sur laquelle s'appuyer pour progresser.
    Kropernic

  5. #5
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    SqlCommand est une classe et non une structure, je ne comprend donc pas le gain de performance en utilisant ref.
    http://stackoverflow.com/questions/8...ing-same-types
    http://stackoverflow.com/questions/3...formance-c-net


    Pour l'utilisation de Using(...) ça ne change pas grand chose: le using va être transformé en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    try {} finally {obj.Dispose();}
    Le dispose ferme la connexion. Le résultat est le même (même si moi aussi je préfère utiliser using)

    Je suis d'ailleurs en total désaccord avec lui quand, dans un autre article, il explique qu'il ne perd plus son temps à faire une couche DAL séparée et qu'il mixe tout dans la BLL car, après tout, changer de DB n'arrive que très rarement dans la vie d'un développeur.
    Je suis plutôt d'accord avec sa façon de faire, à condition de n'utiliser que des procédures stockées (D'ailleur j'avais déjà défendu cette vision dans un autre post qui parlait DAL, DTO, POCO, et je ne sais plus quels acronymes). En effet même si tu changes de base de données, la couche d'accès reste la même à 1 ou 2 détails près (par exemple certains SGBD ne supporte pas les noms de plus de 30 caractères)

    Comme l'a souligné Hervé, il n'a fait qu'une traduction. Il n'est donc pas à blâmer (personne ne l'est en fait je crois)
    Je ne le blâme pas, j'essaye juste de comprendre les choix techniques.
    De plus il n'est pas interdit d'annoter la traduction, ce qui a mon sens ajouterais une vraie plus-value, surtout que le traducteur a fait des modifications pour créer sa DAL. Rien ne l'empêche d'expliquer ces modifications et pourquoi il les a faites.

  6. #6
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par meziantou Voir le message
    Citation Envoyé par Kropernic Voir le message
    Comme l'a souligné Hervé, il n'a fait qu'une traduction. Il n'est donc pas à blâmer (personne ne l'est en fait je crois).
    Je ne le blâme pas, j'essaye juste de comprendre les choix techniques.
    De plus il n'est pas interdit d'annoter la traduction, ce qui a mon sens ajouterais une vraie plus-value, surtout que le traducteur a fait des modifications pour créer sa DAL. Rien ne l'empêche d'expliquer ces modifications et pourquoi il les a faites.
    Ne vous faites pas de soucis, je ne me sens pas blâmé. (comme je l'ai indiqué au début, je ne connais pas forcément la raison de certains choix de l'auteur)

    J'ai simplement fait une traduction le plus fidèle possible des articles.

    Je préférais laisser les lecteurs se faire leurs propres idées, et ne pas orienter leurs avis par des choix personnels. (Après la discussion est là pour échanger)
    _______________________

    Je travaille sur de petits projets. (Donc j'essaye d'anticiper le fait qu'un jour ma DAL pourra utiliser d'autres BDD.) Précision je travaille avec VB.

    J'avais déjà créé ma DAL qui pouvait me renvoyer des DataSet, des DataTable, ou des info plus ciblées (une info avec ExecuteScalar, un dictionnaire, ...). Mais pour un ensemble de données typées, je retournais un jeu de données de type DbDataReader avec lequel je travaillais hors de ma DAL générique — une partie DAL appli — donc réécriture de code sensiblement le même sur le principe (il existe d'ailleur un article abordant le sujet de ce problème de réécriture fastidieux).

    L'article m'a permit de trouver ce que je cherchais, les DTO.

    J'ai intégré dans ma DAL que les méthodes GetSingleDTO et GetListDTO (pas le reste) en les transformant (pour utiliser les requêtes paramètrées). En créant une bibliothèque DTO de référence (DTOBase, DTOParser, et en transformant DTOParserFactory en une fabrique générique — sinon les méthodes GetSingleDTO et GetListDTO étaient inutilisables)

    Il s'agit donc dans mon cas d'une utilisation personnelle très ciblée. Et je me suis servi de ces articles pour compléter l’existant. (voilà pour les explications)
    _______________________

    Ayant traduit les articles pour mes travaux personnels, je me suis dit que cela pouvais être utile à d'autres. Echanger des idées pour apprendre...


    [Edit] Vu qu'il n'y a pas eu d'autres messages, je complète ma réponse.

    Citation Envoyé par meziantou Voir le message
    SqlCommand est une classe et non une structure...
    Exact, j'ai été imprécis.
    Il s'agit donc de ne pas faire une copie locale de la référence à command.
    Je n'ai pas d'idée sur les performances. (Je vais regarder tes liens)
    Vu l'utilisation de command qui est faite dans la méthode je ne vois pas ce qui pourrai orienter le choix du passage de paramètre par valeur ou par référence. (perso, je ne passe plus un paramètre de type command à mes méthodes GetSingleDTO et GetListDTO mais une requête, j'ai profondément modifié leurs utilisations pour les rendre très générique.)

    Pour ceux qui souhaite une petite explication sur le passage de paramètre voir ce tuto : Passage de paramètres en C#
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  7. #7
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2007
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 677
    Points : 2 137
    Points
    2 137
    Par défaut
    Citation Envoyé par rv26t Voir le message
    Exact, j'ai été imprécis.
    Il s'agit donc de ne pas faire une copie locale de la référence à command.
    Je n'ai pas d'idée sur les performances. (Je vais regarder tes liens)
    En l'occurrence, passer une variable de type référence par référence ça couterai davantage que de la passer par copie (même principe pour les variables de type valeur qui prennent très peu de place en mémoire). Bon le coût est certainement dérisoire dans 99,99% des cas, mais c'est pas mal de le noter ^^
    Le WIP de The last bastion, mon projet de jeu-vidéo (un TD en 3D)

    Mon portfolio / Ma page fb

  8. #8
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut Non !
    Bonjour,

    Bon je vais l'annoncer directement, je ne suis pas du tout fan de l'article. Pourquoi ? Voila les raisons :

    Déjà il y a des erreurs dans le design du code, contraindre un héritage pour rien vers commonbase juste pour récupérer des membres statiques n'a pas de sens.
    Ensuite le passage en référence est une économie de pacotille surtout qu'on voit qu'a coté il y a une 15ene d'affectation de propriétés à des valeurs par défaut qu'elles ont déjà.
    Le IsDuplicateEmail en output est discutable alors qu'un index unique sur la colonne de l'email ferrait parfaitement le boulot.
    Bref cela me fait pas mal douter du niveau de l'auteur.

    Ensuite cet article a quasiment 5 ans et traite donc de la première version d'entity framework qui, comme tout le monde le sait, avait ses défauts de jeunesse. Pour moi cet article a une pertinence assez relative aujourd'hui et ne sert pas dans la majorité des cas mais seulement lorsque l'on a des modèles de base de données vraiment complexe.

    Cette phrase :
    ADO.Net Entity Framework peut être de 50 % à 300 % plus lent que ADO.Net utilisant les ordinaux et SqlDataReaders.
    Ne veut pas dire grand chose et même si elle était vrai à l'époque (ce dont je doute) le serait bien moins aujourd'hui.
    Avec l'utilisation des pocos, l'option AsNoTracking, la compilation des requêtes linq et en utilisant pas les includes sur les relations 1-n on arrive au mêmes résultats dans des performances similaires qu'un ado.net basique.
    Et avec l'arrivé de nouvelles mécaniques comme le cache de 2éme niveau on peut avoir des performances supérieures sans effort.

    L'autre intérêt d'entity framework c'est que vous n'êtes pas obligé de l'utiliser partout.
    Vous voulez faire de l'insert de masse ? Vous pouvez faire un bulk insert.
    Une requête trop complexe pour être fait en linq ? Fait une proc stock dédié qui peut même retourner vos entités.

    Bref n'oubliez par une des règles fondamentales en développement : "Ne pas optimiser prématurément" et au contraire garder un code simple plus facilement optimisable et refactorable plus tard sur les vrais points de contention de performance (optimiser les 20% du code qui mange les 80% de performances).

    En multipliant par 100 le nombre de lignes de code de la DAL (par rapport a EF) au delà du temps de développement, on diminue notre capacité a la modifier, optimiser et la maintenir une application ...

  9. #9
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par anthyme Voir le message
    ...
    Ensuite cet article a quasiment 5 ans et traite donc de la première version d'entity framework qui, comme tout le monde le sait, avait ses défauts de jeunesse. Pour moi cet article a une pertinence assez relative aujourd'hui et ne sert pas dans la majorité des cas mais seulement lorsque l'on a des modèles de base de données vraiment complexe.

    Cette phrase :
    ADO.Net Entity Framework peut être de 50 % à 300 % plus lent que ADO.Net utilisant les ordinaux et SqlDataReaders.
    Ne veut pas dire grand chose et même si elle était vrai à l'époque (ce dont je doute) le serait bien moins aujourd'hui.
    Avec l'utilisation des pocos, l'option AsNoTracking, la compilation des requêtes linq et en utilisant pas les includes sur les relations 1-n on arrive au mêmes résultats dans des performances similaires qu'un ado.net basique.
    Et avec l'arrivé de nouvelles mécaniques comme le cache de 2éme niveau on peut avoir des performances supérieures sans effort.

    L'autre intérêt d'entity framework c'est que vous n'êtes pas obligé de l'utiliser partout.
    Vous voulez faire de l'insert de masse ? Vous pouvez faire un bulk insert.
    Une requête trop complexe pour être fait en linq ? Fait une proc stock dédié qui peut même retourner vos entités.

    Bref n'oubliez par une des règles fondamentales en développement : "Ne pas optimiser prématurément" et au contraire garder un code simple plus facilement optimisable et refactorable plus tard sur les vrais points de contention de performance (optimiser les 20% du code qui mange les 80% de performances).

    En multipliant par 100 le nombre de lignes de code de la DAL (par rapport a EF) au delà du temps de développement, on diminue notre capacité a la modifier, optimiser et la maintenir une application ...
    Le but n'est pas de faire le procès des ORM. L'utilisation d'Entity Framework est certainement pratique, mais il existe des cas de figure ou l'on souhaite procéder différemment. (D'ailleurs vous soulignez cette possibilité avec E.F.)
    Dans l'article que j'ai traduit, j'ai trouvé intéressant la partie qui traite des ordinaux, utile lors de traitement de gros volume de données.
    Note personnelle : le problème de réécriture du code, c'est ce qui m'a poussé à rechercher à simplifier (tout basculer sur autre chose n'est pas forcément possible), mais je n'ai que partiellement résolu mon problème.

    Je ne suis pas le seul à chercher dans ce sens.
    Dans un de mes posts précédant (N°6), j'ai indiqué un tuto sur une autre approche (discrètement et en petit c'est vrai).
    Il s'agit de Accès aux données avec Dapper. (Je l'ai découvert très récemment — article paru le 20 octobre 2013.) La critique par rapport aux ORM reste équivalente, mais souligne aussi le problème de productivité lié à l'écriture du code.
    On peut constater avec Dapper que le code se trouve simplifié que se soit au niveau de la Lecture des résultats en tant qu'entités ou de la gestion des Requêtes paramétrées

    Attention, je ne dit pas qu'il est préférable de l'utiliser par rapport à E.F. ou d'autres ORM, mais savoir que cela existe peut s'avérer utile dans certains cas. (Avoir le choix ou connaître d'autres approches)
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par meziantou Voir le message
    - Pourquoi passer les arguments en ref :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected static T GetSingleDTO<T>(ref SqlCommand command) where T : DTOBase
    Ça, c'est typique d'un développeur qui n'a pas bien compris les notions de type valeur/type référence/passage par valeur/passage par référence... Un peu surprenant dans ce cas, vu que l'auteur n'a rien d'un débutant a priori.

    Ça ne sert effectivement strictement à rien de passer un type référence par référence, sauf bien sûr si la méthode affecte un autre objet au paramètre (ce qui n'est pas le cas ici).

    Citation Envoyé par meziantou Voir le message
    - Pourquoi utiliser SqlConnection, SqlDataReader, etc. au lieu de IDbConnection, IDataReader, etc.
    Citation Envoyé par rv26t Voir le message
    J'avoue que je ne sais pas si l'utilisation d'interface peut avoir un impact sur les performances
    A priori ça ne change rien (ou pas grand chose) aux performances, mais ça permet surtout de faire abstraction du SGBD réel, et donc de pouvoir changer de provider facilement.
    Après, cette abstraction est très bien dans le principe, mais malheureusement dans la pratique les SGBD ne sont pas tous équivalents, donc on se retrouve finalement toujours à devoir faire du code spécifique car les dialectes SQL sont un peu différents d'un SGBD à l'autre...

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Ça ne sert effectivement strictement à rien de passer un type référence par référence, sauf bien sûr si la méthode affecte un autre objet au paramètre (ce qui n'est pas le cas ici).
    Bon, j'ai peut-être parlé un peu vite... j'ai fait un petit benchmark, et il y a effectivement une différence de performance. Dans certains cas, le passage par référence est légèrement plus rapide (de 5 à 10%), mais j'ai aussi vu des cas ou c'est au contraire un peu plus lent. Mais je n'ai pas bien réussi à cerner ce qui fait que c'est plus rapide ou plus lent...

    Le code IL généré est un peu plus long pour une méthode qui prend des paramètres par référence, à cause de l'indirection supplémentaire, donc il me semble que ça devrait toujours être plus lent... c'est peut-être à cause du fait qu'il y a une variable de moins à allouer sur la pile.

    Bref, dans un cas comme ça où l'optimisation des performances est le but, ça peut peut-être se justifier ; mais à mon avis le gain de performance lié au passage par référence est insignifiant par rapport au temps pour exécuter une requête sur la DB...

  12. #12
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Il me semble que cette discussion a divergé du sujet principal de cette série d'articles.
    Comme l'a dit tomlev, le passage par référence ou par valeur est un détail dont l'effet sur les performances est largement négligeable par rapport à ce que ces articles nous montrent.
    De plus, le test EF mentionné en lien de l'article traite de la version 3 beta et non de la première version.
    Ceci dit, EF a bien évolué depuis et pas mal de choses sont possibles (notamment le mode Code First) en plus des améliorations de performances.
    Mais pour moi, ce qui pêche avec les ORM, c'est le mode "boîte noire". Quand tu n'es pas un expert du framework, tu ne sais pas ce qu'il se passe sous le capot et tu n'as pas la main pour faire comme tu veux.

    Cette série d'articles a un grand intérêt éducatif car la couche d'accès aux données est réalisée entièrement avec ADO.Net, qui tend a être oublié par les plus jeunes développeurs au profit des ORM. D'autre part, l'implémentation, bien que discutable, présente l'intérêt d'être "au goût du jour" (utilisation de DTO et non de DataSet, entre autres), contrairement aux exemples de code de la MSDN.

  13. #13
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 19
    Points : 22
    Points
    22
    Par défaut
    Bonjour à tous,

    Je viens de lire cet article fort intéressant et je ne sais plus trop quoi penser.

    Passer par ADO et peupler des objets DTO, c'est une chose que je faisais depuis quelques années après avoir abandonné les DataSets, sans connaitre finalement la véritable appellation de ces méthodes.

    En ce moment, je voulais me mettre "au goût du jour" et passer à Entity Framework dont tout le monde parle. D'autant plus avec le mode Code-First qui semble apporter plus de flexibilité, et l'utilisation d'objets DTO.

    De notre coté, on commence par dessiner les classes avec un outil de modélisation qui sert en fait à modéliser une base de données (et pour son coté pratique, on est passés sur MySQL Workbench, malgré que nous travaillons majoritairement sur SQL Server.

    J'ai donc développé un petit générateur de code, qui est capable de lire la structure d'une base de données SQL Server (tables, champs, clés primaires, clés étrangères), puis de boucler sur des fichiers templates que l'on écrit (ce sont des fichiers de code dans lesquels on remplace les noms de tables/champs etc. par des "variables" afin de pouvoir générer par exemple un fichier par table en partant d'un seul fichier template). Je suis donc capable de re-générer le script des create table alter table add foreign key des doigts dans le nez. J'ai donc ajouté un parser capable de lire un script de création de base à la syntaxe MySQL produit par MySQL Workbench. (Vous inquiétez pas, vous comprendrez où je veux en venir)

    Je suis donc capable en une poignée de clics de souris, de :
    - Exporter de MySQL Workbench un script de génération de base au format MySQL
    - Parser le script et générer un script de génération de base au format SQL Server (et donc créer la base de données automatiquement)
    - Lire la structure de la base SQL Server et générer autant de fichiers de code que je veux, donc mes objets DTO, mes Providers pour ma DAL etc.

    Je produisais donc une DAL qui utilise Entity Framework 6, et je me rends compte que :
    1) Ca met une plombe à s'initialiser au lancement de l'appli
    2) Le Lazy Loading ne sert à rien puisqu'on n'a plus le contexte une fois sorti de la DAL
    3) Il faut gérer les propriétés de navigation pour provoquer les insert si celles-ci contiennent un nouvel objet
    etc.

    Et je lis des articles où des gens s'arrachent les cheveux pour faire un truc un peu tricky avec EF, où les gens perdent du temps à tracer les requêtes écrites par le moteur EF afin de les optimiser car trop lourdes etc. Et à chaque fois comme ici la conclusion est "oui mais le code est plus facile à maintenir alors tant pis pour les perfs".

    Sauf que, avec mon super générateur de code :
    1) Rien à maintenir, une fois le template écrit je regénère toute la DAL et tous les DTO en un clic
    2) Je peux même générer directement les requêtes SELECT, INSERT, UPDATE, DELETE via mes templates dans le code, au lieu de créer des procédures stockées (que tous les SGBD ne supportent pas)
    3) Je maitrise donc les ordinaux directement et n'ai même plus besoin de gérer les ordinaux avec PopulateOrdinals

    Alors finalement, que reste-t-il à un ORM face à cela ?

    Quel est votre avis ? Je me demande si parfois il ne vaut pas mieux rester à d'anciennes méthodes (ici ADO) quand celles-ci sont éprouvées et qu'on a une solution pour les rendre faciles à maintenir ...

  14. #14
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    A mon humble avis EF Code-First est une hérésie pour faire plaisir à certains. En effet cela ne fait pas gagner de temps de dev et à mon avis permet uniquement au gens ne maitrisant pas SQL de faire des d’application. Mais peut-on vraiment faire une application sans connaitre SQL ? Je pense même au final que l’on perd du temps à cause de l’effet boite noire que tu décris, des différents problèmes/limitations auxquels on peut être confrontés (il suffit de regarder le nombre important de questions sur ce forum ou d’autres) et du temps de monté en compétence sur la techno afin de bien l’utiliser.

    L’approche Model-First est déjà plus intéressante puisqu’elle permet de générer une quantité plus ou moins importante de code à partir d’un modèle (même si celui-ci est finalement assez pauvre, mais après tout EF n’est qu’un ORM). Si vous partez sur cette approche je vous conseille de regarder ce que propose Matthieu Mezil.


    Les DTO sont également un truc dont je ne comprends pas l’intérêt, en tout cas tels qu’ils sont utilisés dans de nombreux projets. La programmation orientée objet indique qu’un objet contient des données (propriétés) et des comportements (méthodes). A force de faire des DTO, des classes pour la validation, des repository, des factory, etc., et de vouloir suivre "les bonnes pratiques" en faisant des interfaces sans aucun sens dans l’unique but de faire de l’IOC et de pouvoir mettre des petits bouchons (stub) un peu partout, on se retrouve vite avec des modèles anémiques et difficilement maintenable. (J'extrapôle un peu par rapport à vos dire mais malheureusement on voit cela tellement souvent)


    Ecrire un T4 pour générer du code aussi important que celui-ci (il s’agit tout de même des fondations de l’application) n’est pas aisé. Il y a de nombreux cas à gérer et la combinatoire est très compliquée sauf si le code que l’on génère ne fait presque rien (mais les projets évolue et on souhaite toujours générer plus de code). De plus on se retrouve rapidement à le modifier pour l’adapter à chaque projet. Par exemple si je souhaite tracer l’appel aux méthodes ou ajouter un mécanisme de cache (ou les 2 en même temps) il faut créer plusieurs version du template et bien évidemment les maintenir. On se retrouve donc à passer beaucoup de temps sur l’écriture de ces Templates et donc moins sur l’application en elle-même (et ce à chaque projet).

    Une approche basée sur CodeDom ou toute autre représentation en mémoire du code est beaucoup plus intéressante puisqu’elle permet de générer le code « de base » puis d’y ajouter des comportements de manière unitaire. Par exemple pour ajouter des traces il suffit de parcourir la représentation du code et de la modifier. Une fois tous les traitements effectués on génère les fichiers. De plus on peut patcher la génération du code de base sans impacter les « extensions », la maintenance est donc simplifiée. Par contre le coût initial pour mettre en place la première solution est plus important.

    Les ORM génère du code dynamiquement. Je ne dis pas que cela est mal, mais je pense que les procédures stockées ont encore de nombreux avantages :
    - Modifiable sans recompiler l’application
    - Un DBA peut faire son taf plus facilement puisqu’il a toutes les cartes en main
    - Abstraction de la structure de la base de données pour l’application
    - Permission plus fine pour l’application
    - Totalement prédictible sans lancer l’application
    Parfois on n’a pas le choix car le SGBD ne supporte pas les procs stock

    D’un autre côté le développeur n’a pas envie d’écrire de la plomberie (même si ça occupe les développeurs des sociétés de service…). Personnellement je préfère coder des choses où il y a une vraie valeur.
    Doit-on forcément tout faire à la main ou utiliser un ORM ? La réponse est non. En .NET il y a par exemple CodeFluent Entities, un générateur de code basé avec une approche Model-First, qui utilise des proc stock et ADO.NET et dont tout le code est statique/prédictible (aucune requête n’est généré dynamiquement à l’exécution).

    Tu peux également regarder les ORM lite, comme Dapper, qui traitent le strict minimum de choses, mais qui le font bien et simplement. Tomlev a écrit un article sur Dapper si tu souhaites plus d'information http://tlevesque.developpez.com/tuto...s-avec-dapper/

    Comme toujours chaque solution à ses avantages et ses inconvénients. A toi de peser le pour et le contre pour ton besoin et de faire un choix.

  15. #15
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 19
    Points : 22
    Points
    22
    Par défaut
    Je te remercie pour cette réponse détaillée et les liens vers ces articles intéressants. Mon seul bémol sera de dire que ces liens pointent tous vers cette société qui développe Code Fluent, on peut donc supposer que, même s'ils sont pleins de sens, ces articles sont tout de même un peu biaisés pour prêcher pour leur solution.

    Néanmoins, je me rends compte à la lecture que j'ai respecté un certain nombre de leurs principes dans le sens où je pèse le pour et le contre de la génération de code de la même manière que celle décrite, et que j'ai conçu un générateur de code qui se base sur des templates, et qui propose bien finalement l'approche "Model-first" puisque je pars d'un analyseur de structure de base de données pour pondre le code. (En fait, pas le code, mais pour boucler et remplacer les variables dans mes templates. Mon principe, sans rentrer dans les détails, c'est d'avoir des boucles du style "for each table", "for each field", "for each primary key", "for each foreign key", et pour chacun des variables comme le nom, le type sql, le type csharp, la taille/précision, et des blocs conditionnels "if nullable", "if not nullable", "if is primary key", "if is not primary key", "if is foreign key", "if is not foreign key" etc., tout ça pour expliquer que je me laisse une flexibilité totale et que c'est complètement dédié à la génération de code répétitif en fonction d'un modèle de données)

    Néanmoins, génération de code ou pas, on en revient aux mêmes questions : est-ce qu'on génère du code pour encapsuler un ORM comme Entity Framework (qui lui même est plus ou moins un générateur de code, finalement je me dis que je suis en train de mettre deux couches pour rien), ou est-ce qu'on génère du code pour encapsuler ADO ?
    Sans dire que j'ai réinventé Entity Framework (et clairement ce n'est pas le cas), j'ai quand même l'impression d'avoir une solution, malheureusement trop personnelle, qui remplace Entity Framework.

    Ma vraie question intrinsèque était finalement peut être plutôt "est-ce encore une bonne pratique de reposer sur ADO pour l'accès aux données ?"
    Sachant que l'on a écarté via ma méthode les problématiques de "avec ADO, on doit écrire beaucoup de code répétitif, consommateur de temps, difficile à maintenir, avec risques de différences de qualité entre les classes etc."

    Je me pose de plus en plus la question de publier mon générateur de code sur une plateforme open-source ...

  16. #16
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par sierramike Voir le message
    Je me pose de plus en plus la question de publier mon générateur de code sur une plateforme open-source ...
    Personnellement, étant assez réfractaire à EF, je serais pas mal intéressé par ton générateur de code si jamais tu le publies. Si j'ai bien tout compris, ton générateur associé à Dapper pour la plomberie serait une combo assez intéressante.
    Kropernic

  17. #17
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    Pour les modèles anémique il est très facile de trouver des articles sur le sujet. J'ai mis celui-là car je trouve qu'il présente bien le problème. Tu peux également regarder ces articles:
    - http://bodysplash.fr/post/2008/01/14...-grand-melange
    - http://www.martinfowler.com/bliki/An...mainModel.html
    De même je parle de CodeFluent Entities car je pense qu'il s'agit d'un produit permettant réellement l'approche Model-First (et que je l'utilise au quotidien depuis pas mal de temps). Ce produit existe depuis 2005-2006. Ils ont donc une grande expérience sur les outils de génération de code. Les deux articles indiqués ne sont à mon sens pas vraiment biaisés par leur produit. Les articles potentiellement orientés sont sur le blog dédié au produit: http://blog.codefluententities.com.

    La génération de code à partir d'un modèle est quelque chose de très difficile. Premièrement le modèle doit contenir un maximum d'information (et être indépendant d'une techno). A partir du moment où le modèle est limité, le code généré le sera également. Une base de données n'est clairement pas un bon modèle. Il suffit de regarder ce que contient le modèle de CodeFluent par rapport à une base de données pour comprendre que ça n'a rien à voir.

    Personnellement je ne suis pas fan des ORM type EF puisque je ne vois pas de gain de productivité avec leur utilisation, mon avis est donc d'utiliser ADO.NET directement mais cela est juste mon avis.
    Si tu veux tu peux regarder le code généré par CodeFluent Entities pour te donner des idées puisqu'il utilise directement ADO.NET et non un ORM.
    D'un autre côté j'ai l'impression que ton générateur de code ne génère presque rien (CRUD uniquement) tu auras donc encore pas mal de code à écrire pour gérer d'autres requêtes. Un ORM ou micro ORM pourra peut-être t'aider dans cette démarche.
    Bref, à toi de voir.


    N'hésites pas à publier ton code si tu penses qu'il peut servir à d'autres et si tu souhaites avoir des retours.

  18. #18
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Citation Envoyé par sierramike Voir le message
    "est-ce encore une bonne pratique de reposer sur ADO pour l'accès aux données ?"
    Ça dépend du besoin.
    C'est l'éternelle question qui revient systématiquement dans la grande majorité de nos choix techniques : "sur mesure" ou "prêt-à-porter" ? "from scratch" ou "framework" ?
    Je rappelle ici les premiers avantages et inconvénients du sur mesure qui me viennent à l'esprit :
    + L'ensemble du traitement est connu/modifiable.
    + Au plus proche du besoin, donc (théoriquement) au plus optimisé.
    + Pas de montée en compétence, la connaissance s'acquiert au fur et à mesure (valable seulement si on est présent et impliqué dès l'origine du projet).
    - Productivité moindre (tuyauterie, outillage, générateurs,... Tout est à faire).
    - Aucune aide possible extérieure (sur Internet, personne ne vous entendra crier...).
    ... Et inversement dans le cas d'un framework.

    Concernant la couche ADO.Net (n'oubliez pas le .Net derrière, car ADO existait avant .Net et ce n'est pas tout à fait pareil...), une chose est sûre, c'est qu'elle est encore aujourd'hui, et quoi qu'en disent les défenseurs de tel ou tel ORM, la couche de plus bas niveau (native au framework .Net) et donc la plus performante (si elle est correctement implémentée) en terme d'accès aux données stockées sur SGBDR.

    Concernant EF en particulier, j'ai bien pratiqué la version 5 sur un projet récent en mode Model-First (diagrammes UML qui génèrent des entités EF qui génèrent la base). Les deux gros points de gain de productivité qui sont fondamentaux pour moi sont :
    - La génération et la mise à jour automatique de la base de données à partir du code source : hyper pratique quand on sait l'utiliser... Mais j'ai perdu bcp de cheveux au début.
    - L'écriture des requêtes en LinqToEntities. Les requêtes sont validées à la compilation, c'est juste indispensable quand ton modèle change régulièrement. Mais c'est à double tranchant car des développeurs de l'équipe ont écrit des requêtes énormes (dont le SQL résultant faisait plus de 3000 lignes !) et qui se sont avérées peu performantes et difficiles à redécouper a posteriori.
    sierramike, je ne crois pas que ces deux points soient gérés actuellement par ta solution ?

    Citation Envoyé par sierramike Voir le message
    est-ce qu'on génère du code pour encapsuler un ORM comme Entity Framework, ou est-ce qu'on génère du code pour encapsuler ADO ?
    Je dirais plutôt qu'on souhaite encapsuler la couche de persistance des données.

    Citation Envoyé par sierramike Voir le message
    Je me pose de plus en plus la question de publier mon générateur de code sur une plateforme open-source ...
    Ça, c'est toujours une bonne idée !

  19. #19
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par Skalp Voir le message
    Plein de choses intéressantes...
    Vu que j'ai un utilisateur actif d'EF sous la main, j'aimerais savoir... Voici quelques questions que je me pose et auxquelles je n'ai pas encore trouvé de réponse concernant EF :
    1. La base de données qui a été générée par EF5 via le diagramme UML était-elle correctement normalisée ?
    2. Les contraintes d'intégrité référentielle étaient-elles mises en place ?
    3. Faut-il créer à la main les contraintes CHECK nécessaire pour valider certaines règles de gestions ?
    4. Comment cela se passe-t-il lorsque la base sur laquelle va travailler le nouvel applicatif doit s'intégrer dans une base existante ? Comment sait-il dans quel(s) schéma(s) de la DB créer les objets ?


    Voilà déjà un début. Personnellement, je suis un défenseur de l'utilisation de ADO.NET. Alors oui, lors de la première fois, il y a de la plomberie à faire (après on réutilise). Mais lors de la première fois avec EF, il faut apprendre à l'utiliser. Donc la perte de temps doit être à peu près équivalente. Autre point consommateur de temps, je dessine moi-même la base de donnée et tout ce qui va avec (contraintes, procédures, indexes). Si on me dit que EF fait ça aussi bien que moi, alors ok, je m'inclinerai. Mais vu que tu cites toi-même des exemples de requêtes sql générées faisant des milliers de lignes, cela m'étonnerait assez. En fait, je ne vois comment un générateur (qui se doit d'être généraliste car devant s'adapter à toutes les demandes) arriverait à produire du SQL qui soit adapté à la demande spécifique faite par chaque application.
    Kropernic

  20. #20
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    La base de données qui a été générée par EF5 via le diagramme UML était-elle correctement normalisée ?
    Si tu modélises correctement oui (encore heureux).

    Les contraintes d'intégrité référentielle étaient-elles mises en place ?
    Seule les clés primaires et étrangères sont gérées.
    Les contraintes d'unicités sont théoriquement supportées, mais difficilement applicable avec EF Model-First: http://blogs.msdn.com/b/efdesign/arc...framework.aspx.

    Faut-il créer à la main les contraintes CHECK nécessaire pour valider certaines règles de gestions ?
    Les contraintes de vérification des données ne sont pas gérées. En même temps je vois mal comment le faire puisqu'elles sont spécifiques à ton besoin.
    Par contre tu dois donc les créer et les déployer à la main, il n'y a pas d'aide à ce niveau .

    Comment cela se passe-t-il lorsque la base sur laquelle va travailler le nouvel applicatif doit s'intégrer dans une base existante ? Comment sait-il dans quel(s) schéma(s) de la DB créer les objets ?
    Entity Framework Model First ne gère pas les schémas. Cela semble possible avec Code First et la dernière version.
    => Avis personnel: j'ai l'impression qu'une fois de plus Microsoft délaisse le côté modélisation qui présente pourtant un intérêt indéniable s'il est bien fait.

    En fait, je ne vois comment un générateur (qui se doit d'être généraliste car devant s'adapter à toutes les demandes) arriverait à produire du SQL qui soit adapté à la demande spécifique faite par chaque application.
    En fait un générateur ne doit pas permettre de générer tout et n'importe quoi. Dans chaque projet tu auras du code spécifique. Par contre un générateur de code doit permettre
    - De générer ce qui est industrialisable
    - D'étendre le code généré
    - De remplacer le code généré qui ne te correspond pas par ton code. Par exemple si une proc stock n'est pas optimisée ou qu'une méthode ne fait pas exactement ce que tu souhaites, tu dois pouvoir la remplacer par la tienne.
    - De regénérer encore et encore sans perdre les customisations et sans perdre de temps (mauvaise migration de la base de données, migration de type DROP TABLE, CREATE TABLE, etc.)

    [mode pub=on]
    Je vais enfoncer le clou avec l'approche proposée par CodeFluent Entities pour te montrer qu'un outil peut quand même être utile s'il a été bien pensé.

    Persistence
    Pour chaque entité modélisée, tu peux spécifier son nom, le nom de la table, le schéma. L'outil génère des tables, des vues, des proc stock statiques (rien n'est généré dynamiquement à l'exécution). Bien évidemment toutes les proc stock ne peuvent pas être générées. Dans ce cas l'outil te permet de créer ta propre proc stock mais garde le contrôle sur la définition de celle-ci (nom, arguments, type de retour) afin de pouvoir générer le code d'accès (mapping c#). Tu peux également remplacer une proc stock générée par la tienne.

    Les changements sont facilement absorbés. Si tu ajoutes une propriété et que tu regénères, l'outil regarde l'état actuel de la base de données et effectue les modifications nécessaires pour atteindre la cible et cela sans perte de données. Pour cela il génère un script SQL différentiel (rejouable sur d'autres environnements). Bien évidemment si tu ajoutes une contrainte non valide avec les données actuelles, ou que tu essayes de convertir d'un type à un autre alors qu'ils sont incompatibles alors tu auras une erreur que TU pourras à priori facilement résoudre.

    L'outil ne permet pas de modéliser des Trigger par exemple. Par contre il te permet de créer un fichier SQL que tu peux intégrer à différentes étapes du déploiement (Après la création des schémas, des tables, des foreign keys, des procédures, etc.)

    Il y a aussi une notion personnalisable de convention de nommage pour s'adapter à chaque projet (avoir des noms de table en majuscule par exemple).

    C# ou VB.NET
    - Les classes sont partielles ce qui d'étendre facilement le code généré.
    - Les méthodes sont virtuelles (sauf si tu indiques le contraire dans le modèle).
    - Tu peux également ajouter du code custom dans différentes méthodes générées. Par exemple avant la sauvegarde (OnBeforeSave), après la sauvegarde (OnAfterSave), à la lecture du DataReader (OnReadRecord).
    - Le code généré se base sur CodeDom, tu peux donc tout à fait modifier le code avant que celui-ci ne soit transformé en fichiers C# ou VB.NET.


    Tu vois bien que l'outil ne permet pas de tout faire mais que tout est fait pour que tu puisses y inclure ton code custom facilement. L'idée n'est pas de faire un tour complet du produit mais uniquement d'insister sur le fait qu'un outil (celui-là ou un autre) peut être utilisé sur de vrais projet et permettre de gagner du temps.

    Penses-tu que tu puisses faire de même avec EF? Pour moi la réponse est non.

Discussions similaires

  1. Réponses: 1
    Dernier message: 19/02/2016, 21h50
  2. Réponses: 26
    Dernier message: 06/10/2014, 16h17
  3. Réponses: 0
    Dernier message: 12/12/2013, 00h33
  4. Réponses: 0
    Dernier message: 18/11/2013, 21h49
  5. Réponses: 0
    Dernier message: 18/11/2013, 21h46

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