Licence CC BY

La couche de sauvegarde : les entités

Dernière mise à jour :

Nous allons coder notre application grâce à l’approche code first. L’avantage c’est que nous avons déjà codé une partie de nos modèles, il n’y aura plus qu’à les intégrer à Entity Framework.

L'entité, une classe comme les autres

Lorsque nous créons une application web, nous devons répondre à un besoin métier.

Ce besoin vous permet de comprendre qu’il y a des structures de données qui sont courantes. C’est de là que naissent les classes métier aussi appelées "entités" dans notre cours.

Pour l’instant, ces classes métiers seront très légères, puisque leur premier but est avant tout de préparer la sauvegarde de leurs données en base. On dit alors que notre but est la persistance des données. C’est-à-dire qu’on veut les rendre disponibles même une fois que la page a été exécutée.

Plus tard dans le cours, nous étofferons ces classes qui mériteront alors leur nom de "classe métier".

Nous avons décidé que nous allions créer un blog. De manière basique, un blog se représente ainsi :

le contenu principal est appelé article.

Un article est composé de plusieurs choses :

  • un titre ;
  • un texte ;
  • une thumbnail (miniature ou imagette en français).

Les articles pourront être commentés par différentes personnes.

Un commentaire est composé de plusieurs choses :

  • un titre ;
  • un texte ;
  • un renvoi vers le site web de l’auteur du commentaire.

Et ainsi de suite.

Comme vous pouvez le constater, ces descriptions amènent à une conclusion simple : les "entités" peuvent être représentées par de simples classes telles qu’on a l’habitude de manipuler.

Il y a cependant une nécessité qui est imposée par le fait qu’on va devoir persister les objets : il faut qu’ils soient identifiables de manière unique.

A priori, deux articles peuvent avoir le même titre, ce dernier ne peut donc pas être l’identifiant de l’article.

Le texte peut être très long, comparer deux textes pour trouver l’identifiant du site ne serait donc pas performant.

C’est pour cela que nous allons devoir créer un attribut spécial. Par convention, cet attribut s’appellera ID et sera un entier.

Une version simplifiée (et donc incomplète) de notre classe Article serait donc :

public class Article{ //important : la classe doit être publique

    public int ID {get; set;}
    public string Titre{get; set;}
    public string Texte{get; set;}
    public string ThumbnailPath{get; set;}

}
Structure simplifiée de la classe Article

Vous pouvez le constater, notre classe est surtout composée de propriétés simples (int, string, float, decimal) publiques avec un accès en lecture et en écriture.

Vous pouvez aussi utiliser certains objets communs tels que :

  • DateTime
  • TimeSpan
  • Byte[]

Vous trouverez un récapitulatif complet des types supportés par défaut sur msdn.

Cela signifie que les struct ne sont pas compatibles par défaut. N’utilisez que les objets simples ou les objets que vous avez vous-même créés.

Customiser des entités

Le comportement par défaut

Avant de personnaliser les entités, tentons de comprendre leur comportement par défaut.

Premièrement, si votre entité est bien enregistrée, elle sera transformée en table SQL. Cette table portera le même nom que l’entité. Les colonnes prendront le nom de l’attribut qu’elles cartographient.

ID(int)

Titre(Varchar128)

Texte(Text)

ThumbnailPath

1

Premier article

Bonjour à tous, bienvenue sur mon blog !

/images/coeur.png

2

Billet d’humeur

Je suis trop heureux d’avoir créé mon blog !

/images/content.png

……………………….

……………….

La table SQL générée à partir de notre entité

<-

Changer le nom des tables et colonnes

Dans certaines applications, les gens aiment bien faire en sorte que les tables aient un préfixe qui symbolisent leur application. Cela permet, par exemple, de mettre plusieurs applications dans une seule et même base de données, sans changer l’annuaire des membres.

Pour cela, il faudra expliquer à EntityFramework que vous désirez changer le nom de la table voire des colonnes grâce aux attributs [Table("nom de la table")] et [Column("Nom de la colonne")].

[Table("blog_Article")]
public class Article{
    public int ID {get; set;}
    [Column("Title")]
    [StringLength(128)]
    public string Titre{get; set;}
    [Column("Content")]
    public string Texte{get; set;}
    public string ThumbnailPath{get; set;}
}
Personnalisation de la classe

Les données générées par la base de données

La base de données peut calculer certaines valeurs pour vos entités.

Inconsciemment nous avons déjà mis en place cette fonctionnalité précédemment. Rappelez-vous, je vous ai dit qu’une entité avait besoin d’un attribut ID.

Cet attribut, par défaut est compris par le programme comme possédant les particularités suivantes :

  • nom de colonne = ID ;
  • entiers positifs ;
  • valeurs générées par la base de données : de manière séquentielle et unique à chaque instance.

Si nous devions coder cela nous mettrions :

public class Article{
    [Column("ID")]
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.IDENTITY)]
    public int ID_That_Is_Not_Conventional{get; set;}
    [Column("Title")]
    [StringLength(128)]
    public string Titre{get; set;}
    [Column("Content")]
    public string Texte{get; set;}
    public string ThumbnailPath{get; set;}
}
Génération de l’ID par la base de données

Préparer le contexte de données

Nous allons vouloir enregistrer nos données dans la base de données. En génie logiciel on dit souvent que l’on assure la persistance des données. Comme dans les jeux en ligne à monde persistant en somme.

Lorsque vous utilisez EntityFramework, le lien fait entre la base de données et votre application se situe au niveau d’un objet appelé DbContext.

Si vous visitez un peu les classes que Visual Studio vous a générées, vous ne trouvez aucune classe appelée DbContext. Par contre vous trouvez une classe nommée ApplicationDbContext qui hérite de IdentityDbContext.

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }
ApplicationDbContext

En fait, comme nous avons créé une application web avec authentification, VisualStudio a préparé un contexte de données qui pré-enregistre déjà des classes pour :

  • les utilisateurs ;
  • leur informations personnelles (customisable) ;
  • leur rôle dans le site (Auteur, Visiteur, Administrateur…) ;
  • les liens éventuels avec les sites comme Facebook, Twitter, Google, Live…

IdentityDbContext est donc un DbContext, c’est là que la suite se passera.

Prendre le contrôle de la base de données

Avant toute chose, comme nous sommes en plein développement nous allons faire plein de tests. Ce qui signifie que nous allons vouloir souvent changer la structure du modèle.

Nous verrons plus tard qu’il existe un outil très puissant pour permettre de mettre à jour une base de données, qu’on appelle les migrations. Pour simplifier les choses, nous ne les mettrons en place qu’un peu plus tard.

Pour l’instant, il faudra que nous supprimions puis recréions la base de données à chaque changement.

Pour cela, regardez le dossier App_Data. Faites un clic droit, puis Ajouter > Nouvel élément.

Nouvel Élément
Nouvel Élément

Sélectionnez "Base de données SQL Server" (selon votre version de Visual Studio, il précisera ou pas (LocalDb)). Donnez-lui le nom sqldb.

Créez la base de données
Créez la base de données

Maintenant, allons à la racine du site et ouvrons le fichier Web.config. Trouvons la connectionString nommée DefaultConnection et changeons l’adresse de la base de données pour faire correspondre à sqldb.mdf :

<connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\sqldb.mdf;Initial Catalog=aspnet-Blog-20141014093301;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>
Web.config ConnectionString

Persister une entité

Pour persister une entité, il n’y a qu’une seule ligne à ajouter à notre DbContext : public DbSet<TEntity> Nom { get; set; }.

Ce qui donne, dans le cas des articles :

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }
        public DbSet<Article> Articles { get; set; }
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }
Les articles seront persistés

Et cela sera comme ça pour toutes nos entités.

Petite astuce appréciable : lorsque vous créez une nouvelle entité, ajoutez-la tout de suite au contexte. Une fois cela fait, vous aurez accès au scafolding complet pour les contrôleurs.