Asp.net Core Comment Se Connecter Avec Une Base De Donnée Mysql

02 Mar 2021

Luigi, le patron de la pizzeria en bas de ta rue souhaite que tu lui crées une application Click And Collect pour booster ses ventes à emporter et aussi pour son organisation. Il a entendu dire qu’il fallait une présence sur internet même pour les petits commerces et il a donc acheté un hébergement chez OVH pour son site.

Le problème est qu’OVH n’utilise pas SQL Server de Microsoft comme SGBD (système de gestion de base de données) mais plutôt MySql, PostgreSql ou MariaDB.

Tu aimerais ne pas perdre de temps à apprendre un autre langage et framework (genre Ruby On Rails) et utiliser ce que tu connais le plus ASP.NET Core et C#.

Pour ce projet, tu devras adapter ton SGBD en MySql.

L’avantage de bosser sur ASP.NET Core est de pouvoir distribuer ton application sur un serveur autre que Microsoft (De toute façon, ils ne veulent plus gagner autant d’argent et se mettent de plus en plus à l’open source). Donc de pouvoir déployer ton app sur Heroku, ou un serveur mutualisé comme OVH.

Dans cette ressource, tu vas apprendre à créer une connexion entre une base de données MySql et ton application ASP.NET Core.

1. Historique et Contexte

OVH est une entreprise Française créé en 1999 par Octave Klaba et propose des prestations de cloud public et privé, des serveurs dédiés, de l’hébergement mutualisé.

Pour déployer ton app sur OVH (par exemple), tu auras besoin de créer une connexion entre ton app et une base de données gérée sous MySql.

Pour ça, tu auras besoin de télécharger MySql (c’est en open source) ou comme moi utiliser une image de MySql via Docker.

Docker est une autre entreprise Française fondé en 2013 par Solomon Hykes, Andrea Luzzardi, Francois-Xavier Bourlet qui permet de créer des conteneurs isolés d’applications et ses dépendances.

Installes Docker dans ton environnement de travail. Dès que tu es prêt.e, continues la ressource.

2. La Ressource

2.1 Récupérer une image sur Docker Hub

Si tu décides d’installer MySql, tu vas remarquer que tu installes en même temps un ensemble d’outils pour travailler avec MySql. Par moment, tu peux rencontrer des bugs suite à l’installation souvent à cause de problèmes de compatibilités entre la version MySql et ton Os.

Pour éviter ça, tu peux utiliser une image de MySql dans un conteneur Docker. Pour rendre cela encore plus simple, Docker propose un Hub où tu peux télécharger des images fonctionnelles des applications que tu veux utiliser.

Si ensuite tu souhaites utiliser d’autres images pour ton kif, utilises des images officielles (proposées par l’équipe du projet) ou des images approuvées.

Sur ton terminal, tu as juste à taper le code qu’ils te proposent :

$ docker pull mysql

Avec cette ligne, tu vas télécharger l’image mysql dans Docker (N’oublies pas de lancer Docker sur ton ordinateur au préalable).

Une Image Docker contient tout ce que tu as besoin d’une application :

  • les dépendances de l’application
  • les processus qui vont se déclencher au moment du lancement de l’application.

Cette image sera stockée dans un conteneur Docker. Pour voir si tu as bien l’image dans ton Docker, tu tapes ce code sur le terminal :

$ docker images

2.2 Création du fichier yaml

Avant de lancer ton image MySql, tu vas d’abord configurer un fichier yaml. Rends toi dans le répertoire de ton projet et crées ce fichier stack.yaml avec ce code à l’intérieur :

version: '3'

services:

  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: Ton_Mot_De_Passe
    ports: 
      - 3306:3306

N’oublies pas de changer Ton_Mot_De_Passe avec un mot de passe.

Puis lances le code suivant sur ton terminal :

$ docker-compose -f stack.yaml up

Au lancement, Docker va ouvrir l’image et te créer un environnement qui tournera sur le port 3306.

Non ton terminal ne bug pas, il fait tourner ton image Mysql. Remontes un peu toutes les lignes jusqu’au moment de l’exécution du dernier code pour récupérer le nom du service que Docker à créé. Chez moi c’est docker_database_1.

2.3 Connexion dans le conteneur

Ok, maintenant que tu as un conteneur qui tourne, tu vas lancer ton application MySql à l’intérieur.

Tapes le code suivant dans un autre terminal :

$ docker exec -it docker_database_1 mysql -h localhost -P 3306 -u root -pTon_Mot_De_Passe

Là, tu demandes au service Docker de lancer MySql. Remplaces docker_database_1 par le nom attaché au service Docker et Ton_Mot_De_Passe par ton mot de passe sans laisser d’espace après -p.

Si tout se passe bien, tu devrais avoir MySql en mode ligne de commande. Pour voir si tu as quelques choses sur ce gestionnaire, testes en tapant ce code :

$ show databases;

2.4 Configurer EntityFramework pour utiliser MySql

2.4.1 Importer les packages NuGet

Tu vas ensuite installer les librairies (Packages NuGet) que tu auras besoin pour faire tourner ton application :

  • EntityFrameworkCore comme ORM (Object Relational Mapping) pour relier les tables de ta base de données en classe C#.
  • EntityFrameworkCore.Design
  • Pomelo.EntityFrameworkCore.MySql

Pour ça, tu vas faire un clic droit sur le nom de ton projet puis cliquer sur Gérer les packages NuGet.

Pour EntityFramworkCore, n’oublies pas de prendre la version correspondant à la version de ton application. Celle que tu as choisi au moment de sa création.

2.4.2 Créer un répertoire Models

Partant du principe Code First, tu vas d’abord écrire tes classes C# dans un dossier Models puis les transposer en tables dans ta base de données.

Ajoutes à ton projet un dossier Models puis dedans ajoutes une classe Pizza et une classe Ingredient parce que Luigi veut pouvoir gérer les stocks de disponible.

Dans la classe Pizza, tapes le code suivant entre les accolades de la méthode public class Pizza :

  [Key]
  public int Id { get; set; }
  public string Name { get; set; }
  public double Price { get; set; }
  public bool IsVegge { get; set; }
  public Ingredient Ingredient { get; set; }

Dans la classe Ingredient, tapes le code suivant entre les accolades de la méthode public class Ingredient :

  [Key]
  public int Id { get; set; }
  public string Name { get; set; }

Ces classes seront les tables Pizzas et Ingredients que tu retrouveras dans ta BD après.

2.4.3 Créer un conteneur d’entités ApplicationDbContext

Tu crées ensuite une autre classe ApplicationDbContext dans ton dossier Models. Cette classe sera le conteneur d’entités qui va prendre la responsabilité de mapper les tables avec les classes C#.

Tapes le code suivant comme sur l’image en dessous :

public class ApplicationDbContext : DbContext
{
  public ApplicationDbContext(DbContextOptions options) :base(options) {}

  public DbSet<Pizza> Pizzas { get; set; }
  public DbSet<Ingredient> Ingredients { get; set; }
}

La classe ApplicationDbContext va coordonner les fonctionnalités de Entity Framework pour les classes Pizza et Ingredient, c’est pour cela qu’elle hérite de DbContext. Ce conteneur va spécifier quelles classes seront inclus dans le modèle en BD. Ici, la propriété DbSet<Pizza> Pizzas est un set d’entité qui deviendra la BD ayant comme table Pizza.

Avec : base(options), tu renvois les options au constructeur de la classe DbContext qui seront passées en argument lors de l’exécution.

2.4.4 Modifier le fichier Startup.cs

Dans le fichier Startup.cs, tu vas ajouter le conteneur (ApplicationDbContext) comme service dans la méthode ConfigureServices :

  services.AddDbContext<ApplicationDbContext>(options => 
          options.UseMySql(
              Configuration.GetConnectionString("MyMysqlConnexion"),
              options =>
              {
                  options.EnableRetryOnFailure();
              })
              );

Là tu viens d’ajouter un service qui va être appelé à l’exécution de ton programme. En gros, tu dis à ton app d’utiliser les services de MySql avec les connexions qui se trouvent dans ton fichier appsettings.json.

2.4.5 Modifier le fichier appsettings.json

Maintenant, tu vas modifier le fichier appsettings.json pour transmettre les informations concernant ta BD qui se trouve sur MySql.

Ajoutes après la dernière ligne le code suivant :

  "ConnectionStings": {
    "MyMysqlConnexion": "Server=127.0.0.1;Port=3306;Uid=root;Password=abcd@1234;Database=DBLuigiPizza"
  }

Uid est le nom d’utilisateur de la base de données, ici tu peux le laisser sur root. Modifies abcd@1234 par ton Ton_Mot_De_Passe inscrit dans le fichier stack.yaml et donnes un nom à la base de données (DBLuigiPizza) que tu veux retrouver dans MySql.

2.4.6 Lancer PM (Package Manager)

Ensuite tu vas lancer la console du Gestionnaire de package pour créer les fichiers de migrations. Ces fichiers de migrations te permettront de créer une relation durable avec ta BD sur MySql.

Si tu utilises VS sous Windows :

Commences par lancer un Générer une solution puis tester si tu as les outils nécessaires pour travailler. Dans la console, tapes le code suivant :

  PM> dotnet ef

Si tu vois une licorne c’est que tu as les outils nécessaires, sinon tu dois taper ce code :

 PM> dotnet tool install --global dotnet-ef

Si tu ne rencontres aucun autre soucis, retapes la première commande et si tu as bien la licorne continues.

Ensuite tu vas créer un dossier Migrations directement avec la console :

 PM> dotnet ef migrations add PremierMigration --project NomDuProjet

Remplaces NomDuProjet par le nom de ton projet.

Si tout se passe bien, tu devrais avoir un nouveau dossier Migrations qui a été créé.

Si tu as une erreur Use dotnet build, fais Générer la solution et ça devrait passer.

Pourquoi faire un Générer la solution ? Lorsque tu modifies des fichiers statics de ton projet comme tu l’as fait avec le fichier appsettings.json, tu dois lancer un Générer pour que ton projet le prenne en compte.

Dernier code à taper sur la console :

 PM> dotnet ef database update --project NomDuProjet

Remplaces NomDuProjet par le nom de ton projet. Si tout se passe comme prévu, tu vas avoir ta DB de créer sur MySql.

Si tu es sur Mac :

Tu vas faire un clic droit sur le nom du projet puis Tools puis Open in terminal. Ton terminal devrait ouvrir une autre fenêtre.

Lances un Générer une solution puis testes si tu as les outils nécessaires pour travailler. Dans la console, tapes le code suivant :

$ dotnet ef

Si tu vois une licorne c’est que tu as les outils nécessaires, sinon tu dois taper ce code :

 $ dotnet tool install --global dotnet-ef

Si tu ne rencontres aucun autre soucis, retapes la première commande et si tu as bien la licorne continues.

Ensuite tu vas créer un dossier Migrations directement avec la console :

 $ dotnet ef migrations add PremierMigration

Remplaces NomDuProjet par le nom de ton projet.

Si tout se passe bien, tu devrais avoir un nouveau dossier Migrations qui a été créé.

Pourquoi faire un Générer la solution ? Lorsque tu modifies des fichiers statics de ton projet comme tu l’as fait avec le fichier appsettings.json, tu dois lancer un Générer pour que ton projet le prenne en compte.

Dernier code à taper sur la console :

 $ dotnet ef database update

Remplaces NomDuProjet par le nom de ton projet. Si tout se passe comme prévu, tu vas avoir ta DB de créer sur MySql.

Il se peut que l’update te renvoie une erreur de type can't connect to database blablabla..., tu peux corriger cette erreur en créant un utilisateur à la place de root. Pour ça, sur le terminal où est lancé MySql, tu peux taper les codes suivant :

mysql> CREATE USER 'UnNomUtilisateur'@'localhost' IDENTIFIED BY 'Ton_Mot_De_Passe';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'UnNomUtilisateur'@'localhost'
    ->     WITH GRANT OPTION;
mysql> CREATE USER 'UnNomUtilisateur'@'%' IDENTIFIED BY 'Ton_Mot_De_Passe';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'UnNomUtilisateur'@'%'
    ->     WITH GRANT OPTION;

Tu remplaces UnNomUtilisateur par le nom d’utilisateur que tu veux. Et ensuite tu modifies le fichier appsettings.json :

"ConnectionStings": {
    "MyMysqlConnexion": "Server=127.0.0.1;Port=3306;Uid=UnNomUtilisateur;Password=Ton_Mot_De_Passe;Database=DBLuigiPizza"
  }

Ce problème peut arriver à cause du nom du serveur que tu lui envoie c’est à dire 127.0.0.1. Ce type de configuration préfère de vrais serveurs comme tu le verras lorsque tu déploieras ton app en production ou bien localhost.

2.4.7 Vérifier si tout se passe bien

Retournes sur le terminal qui lance MySql et tu vas taper quelques codes pour voir si tout se passe bien :

mysql> show databases;

mysql> use DBLuigiPizza;
mysql> show databases;

2.4.8 Ajouter une Pizza à notre BD

Tu vas ajouter une Pizza pour voir si elle s’enregistre bien en BD. Pour ça, tu crées un controller généré grâce à EF.

Une fois le controller créé, démarres ton projet sur ton navigateur et rends toi à la page pour créer une nouvelle pizza :

Il semble que ça fonctionne, tu dois juste vérifier si c’est bien enregistré en BD :

mysql> select * from Pizzas;

3. Ce que tu dois retenir

  • Tu viens de voir comment créer une image MySql dans un conteneur Docker sans avoir à installer MySql dans ton environnement de travail
  • Tu viens de configurer ton app pour faire du CRUD sur une base de données MySql

4. Pour aller plus loin

  • Si tu veux en savoir plus sur Docker.
  • Si tu veux en savoir plus sur MySql.