Developpez.com - Rubrique .NET

Le Club des Développeurs et IT Pro

Introduction par l'exemple à Entity Framework 5 Code First

Un article de Serge Tahé

Le 2012-10-14 17:10:31, par Serge Tahé, Expert éminent
Bonjour,

J'ai mis en ligne "Introduction par l'exemple à Entity Framework 5 Code First". C'est un tutoriel destiné en priorité aux débutants même s'il peut intéresser d'autres publics.

- Création d'une base SQL Server 2012 à partir d'entités EF5 ;
- Ajout, Modification, Suppression d'entités ;
- Requêtage du contexte de persistance avec LINQ to Entities ;
- Gestion des entités détachées ;
- Lazy et Eager loading ;
- Concurrence d'accès aux entités ;
- Synchronisation du contexte EF5 avec la base de données ;
- Etude d'une application ASP.NET avec une architecture multi-couche ayant EF5 comme ORM et SQL Server 2012 comme SGBD ;
- Portage de l'application ASP.NET sur le SGBD MySQL 5.5.28 ;
- Portage de l'application ASP.NET sur le SGBD Oracle Database Express Edition 11g Release 2 ;
- Portage de l'application ASP.NET sur le SGBD PostgreSQL 9.2.1 ;
- Portage de l'application ASP.NET sur le SGBD Firebird 2.1.

L'application ASP.NET étudiée ci-dessus est celle utilisée dans le document [http://tahe.developpez.com/dotnet/pam-aspnet] où l'ORM était NHibernate et le SGBD MySQL 5. L'ORM est ici remplacé par EF5 et cinq SGBD sont testés.

Outils utilisés :

- Visual Studio Express 2012 pour le bureau ;
- Visual Studio Express 2012 pour le web ;

Vous pouvez sur ce forum, laisser des commentaires, signaler des erreurs, des difficultés, échanger des idées.
  Discussion forum
25 commentaires
  • Envoyé par SoBaKa
    Je ne vois toujours pas ce que ça apporte... une collection ne doit pas être égale à "null" je suis d'accord mais je ne pense pas que le mot clé "virtual" apporte grand chose ici. De plus, tu peux avoir aussi des association qui peuvent être "null".
    À vous lire on dirait que vous n'êtes pas au courant de l'utilité du mot clef virtual sur les propriétés de navigation.

    Donc pour infos le mot clef virtual lorsqu'il est défini sur les propriétés de navigation permet de bénéficier de la fonctionnalité de chargement à la demande (lazy loading) dans l'approche Code First (bien sûr si le développeur ne l'a pas désactivé explicitement dans le code)
  • Et le pourquoi du comment: lorsque tu fais du LazyLoading ou que tu utilises du TrackingChanges, EF (et NHibernate) utilises des proxy (des classes dérivées du type original) pour redéfinir lesdites propriétés

    Ah ui, c'était marqué dans ton lien
  • Luckyluke34
    Membre émérite
    Très beau travail, bravo.

    Si je peux me permettre une critique, je trouve que la différence entre code first et database first aurait mérité plus d'explications. Tel quel, l'article peut laisser croire qu'il s'agit d'un détail technique et que de toute façon la référence est le modèle de données :

    Les entités doivent refléter les tables de la base de données. (p.25)
    Or ce n'est clairement pas le but de l'approche code first (que si j'ai bien compris vous avez été obligé d'utiliser pour des raisons de compatibilité ?) où on va typiquement d'abord construire son modèle objet en essayant de le garder le plus "pur" et le plus dénué possible de toute logique de persistance.
  • BugBlaster
    Membre à l'essai
    Simplement Merci
  • SoBaKa
    Membre averti
    Bonjour Serge,

    A première vue ton introduction me paraît très sympa, beau boulot.

    Par contre j'ai 1 petite question et 1 commentaire :

    Si les champs proposés sont naturels, les mots clés virtual ne le sont pas. C'est une contrainte imposée à la fois par NHibernate et
    EF5 : les champs des entités doivent être des propriétés publiques virtuelles.
    Dans la création d'une entité (page 26), tu indiques que les entités doivent être "virtual"... Utilisant déjà 'EF5 Code First', je n'ai jamais déclaré mes propriétés de cette manière. (Bien qu'ayant déjà vu cela sur des forums anglais). Ma question, quel est l'intérêt de les déclarer "virtual"?

    ------------------

    Page 33, tu souhaites donc initialiser tes noms de table en surchargeant la méthode "OnModelCreating"... C'est assez dommage de procéder de cette manière vu qu'on peut définir le nom de la table et le schéma au niveau de notre entité également.

    En utilisant l'attribut Table qui vient de System.ComponentModel.DataAnnotations.Schema.

    Code :
    1
    2
    3
    4
    5
    [Table("MEDECINS", Schema = "dbo")]
    public class Medecin
    {
      // ...
    }
    Bonne journée.
  • Serge Tahé
    Expert éminent
    @Sobaka

    Dans la création d'une entité (page 26), tu indiques que les entités doivent être "virtual"... Utilisant déjà 'EF5 Code First', je n'ai jamais déclaré mes propriétés de cette manière. (Bien qu'ayant déjà vu cela sur des forums anglais). Ma question, quel est l'intérêt de les déclarer "virtual"?
    Bah... Je croyais que c'était obligatoire. Tu me démontres que non. Au temps pour moi. Pour NHibernate, c'est obligatoire car les méthodes sont redéfinies par NHibernate. J'ai peut-être extrapolé un peu vite pour EF5 ?

    Page 33, tu souhaites donc initialiser tes noms de table en surchargeant la méthode "OnModelCreating"... C'est assez dommage de procéder de cette manière vu qu'on peut définir le nom de la table et le schéma au niveau de notre entité également.
    Code :
    1
    2
    3
    4
    5
    [Table("MEDECINS", Schema = "dbo")]
    public class Medecin
    {
      // ...
    }
    Merci pour l'information. Je savais qu'on pouvait déclarer la table ainsi mais je ne le savais pas pour le schéma.
  • SoBaKa
    Membre averti
    Envoyé par Serge Tahé
    Bah... Je croyais que c'était obligatoire. Tu me démontres que non. Au temps pour moi. Pour NHibernate, c'est obligatoire car les méthodes sont redéfinies par NHibernate. J'ai peut-être extrapolé un peu vite pour EF5 ?
    Apparemment oui :p EF5 ne redéfinit aucunes méthodes des entités. En tout cas encore une fois très bon boulot la dessus, j'ai parcouru en vitesse et je pense que c'est à la portée de tous donc pour ceux qui n'ont pas encore lu, dépechez vous.
  • acesyde
    Membre éclairé
    Le mot clé virtual n'est a utilisé uniquement pour les associations, pour le reste pas besoin, sinon vous risquez d'avoir des soucis au chargement des données (genre la collection toujours à Null).

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class MaTable {
    
    public String MonTitre {get; set;}
    
    public virtual MonAutreTable MonAssociation {get; set;}
    
    public virtual ICollection<MonAutreTable> MaCollection {get; set;}
    
    }
  • SoBaKa
    Membre averti
    Envoyé par acesyde
    Le mot clé virtual n'est a utilisé uniquement pour les associations, pour le reste pas besoins, sinon vous risquez avoir des soucis au chargement des données (genre la collection toujours à Null).

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class MaTable {
    
    public String MonTitre {get; set;}
    
    public virtual MonAutreTable MonAssociation {get; set;}
    
    public virtual ICollection<MonAutreTable> MaCollection {get; set;}
    
    }
    Je ne vois toujours pas ce que ça apporte... une collection ne doit pas être égale à "null" je suis d'accord mais je ne pense pas que le mot clé "virtual" apporte grand chose ici. De plus, tu peux avoir aussi des association qui peuvent être "null".

    Exemple de ce que je trouve plus propre et une association qui peut être "null":

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class MaTable
    {
      public int ID { get; set; }
      public string Name { get; set; }
      public int? RelationID { get; set; }
    
      public MonAutreTable Relation { get; set; }
      public ICollection<EncoreAutreTable> Values { get; set; }
    
      public MaTable()
      {
        if(Values == null) Values = new HashSet<EncoreAutreTable>();
      }
    }
    Pas de virtual... et pleinement fonctionnel
  • acesyde
    Membre éclairé
    Je suis d'accord avec toi pour le constructeur avec l'initialisation.

    Par contre j'ai trouvé pas mal de questions d'utilisateurs sur le web du "pourquoi ma collection est toujours vide".

    La réponse est toujours "rajoute le virtual devant" et l'utilisateur à réussit à retrouver ses infos.

    Pourquoi ?
    Ca je ne sais pas