Code First to a New Database (Création d’une nouvelle base de données avec Code First)
Cette vidéo et cette procédure pas à pas fournissent une introduction au développement Code First ciblant une nouvelle base de données. Ce scénario inclut le ciblage d’une base de données qui n’existe pas et Code First crée, ou une base de données vide à laquelle Code First ajoute de nouvelles tables. Code First vous permet de définir votre modèle à l’aide de C# ou de classes VB.Net. Une configuration supplémentaire peut éventuellement être effectuée à l’aide d’attributs sur vos classes et propriétés ou à l’aide d’une API Fluent.
Regarder la vidéo
Cette vidéo présente le développement Code First ciblant une nouvelle base de données. Ce scénario inclut le ciblage d’une base de données qui n’existe pas et Code First crée, ou une base de données vide à laquelle Code First ajoute de nouvelles tables. Code First vous permet de définir votre modèle à l’aide de C# ou de classes VB.Net. Une configuration supplémentaire peut éventuellement être effectuée à l’aide d’attributs sur vos classes et propriétés ou à l’aide d’une API Fluent.
Présentée par : Rowan Miller
Prérequis
Vous devez avoir au moins Visual Studio 2010 ou Visual Studio 2012 installé pour effectuer cette procédure pas à pas.
Si vous utilisez Visual Studio 2010, vous devez également installer NuGet .
1. Créer l’application
Pour simplifier les choses, nous allons créer une application console de base qui utilise Code First pour effectuer l’accès aux données.
- Ouvrez Visual Studio.
- Fichier - Nouveau ->> Projet...
- Sélectionner Windows dans le menu gauche et l’application console
- Entrez CodeFirstNewDatabaseSample comme nom
- Sélectionnez OK.
2. Créer le modèle
Nous allons définir un modèle très simple à l’aide de classes. Nous les définissons simplement dans le fichier Program.cs, mais dans une application réelle, vous fractionnez vos classes en fichiers distincts et potentiellement un projet distinct.
Sous la définition de classe Program dans Program.cs, ajoutez les deux classes suivantes.
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
Vous remarquerez que nous créons les deux propriétés de navigation (Blog.Posts et Post.Blog) virtuelles. Cela permet la fonctionnalité de chargement différé d’Entity Framework. Le chargement paresseux signifie que le contenu de ces propriétés sera automatiquement chargé à partir de la base de données lorsque vous essayez d’y accéder.
3. Créer un contexte
Maintenant, il est temps de définir un contexte dérivé, qui représente une session avec la base de données, ce qui nous permet d’interroger et d’enregistrer des données. Nous définissons un contexte qui dérive de System.Data.Entity.DbContext et expose un TEntity> DbSet<typé pour chaque classe de notre modèle.
Nous commençons maintenant à utiliser des types à partir de Entity Framework. Nous devons donc ajouter le package NuGet EntityFramework.
- Projet –> Gérer les packages NuGet... Remarque : Si vous n’avez pas l’option Gérer les packages NuGet... vous devez installer la dernière version de NuGet
- Sélectionnez l’onglet Online
- Sélectionner le package EntityFramework
- Cliquez sur Install.
Ajoutez une instruction using pour System.Data.Entity en haut de Program.cs.
using System.Data.Entity;
Sous la classe Post dans Program.cs, ajoutez le contexte dérivé suivant.
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
Voici une liste complète de ce que Program.cs doit maintenant contenir.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace CodeFirstNewDatabaseSample
{
class Program
{
static void Main(string[] args)
{
}
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
}
C’est tout le code que nous devons commencer à stocker et à récupérer des données. Évidemment, il y a un peu de choses en arrière-plan et nous allons examiner cela dans un moment, mais tout d’abord, voyons-le en action.
4. Lecture des & données d’écriture
Implémentez la méthode Main dans Program.cs, comme indiqué ci-dessous. Ce code crée une nouvelle instance de notre contexte, puis l’utilise pour insérer un nouveau blog. Ensuite, il utilise une requête LINQ pour récupérer tous les blogs de la base de données ordonnée par ordre alphabétique par Titre.
class Program
{
static void Main(string[] args)
{
using (var db = new BloggingContext())
{
// Create and save a new Blog
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
var blog = new Blog { Name = name };
db.Blogs.Add(blog);
db.SaveChanges();
// Display all Blogs from the database
var query = from b in db.Blogs
orderby b.Name
select b;
Console.WriteLine("All blogs in the database:");
foreach (var item in query)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
Vous pouvez maintenant exécuter l’application et la tester.
Enter a name for a new Blog: ADO.NET Blog
All blogs in the database:
ADO.NET Blog
Press any key to exit...
Où sont mes données ?
Par convention DbContext a créé une base de données pour vous.
- Si une instance SQL Express locale est disponible (installée par défaut avec Visual Studio 2010), Code First a créé la base de données sur cette instance
- Si SQL Express n’est pas disponible, Code First essaiera d’utiliser LocalDB (installé par défaut avec Visual Studio 2012)
- La base de données est nommée après le nom complet du contexte dérivé, dans notre cas, codeFirstNewDatabaseSample.BloggingContext
Il s’agit simplement des conventions par défaut et il existe différentes façons de modifier la base de données que Code First utilise, plus d’informations sont disponibles dans la rubrique How DbContext Discovers the Model and Database Connection . Vous pouvez vous connecter à cette base de données à l’aide de l’Explorateur de serveurs dans Visual Studio
Affichage -> Explorateur de serveurs
Cliquez avec le bouton droit sur Connexions de données et sélectionnez Ajouter une connexion...
Si vous n’avez pas connecté à une base de données à partir de l’Explorateur de serveurs avant de devoir sélectionner Microsoft SQL Server comme source de données
Connectez-vous à LocalDB ou SQL Express, selon celui que vous avez installé
Nous pouvons maintenant inspecter le schéma créé en premier.
DbContext a travaillé sur les classes à inclure dans le modèle en examinant les propriétés DbSet que nous avons définies. Il utilise ensuite l’ensemble par défaut des conventions Code First pour déterminer les noms de table et de colonnes, déterminer les types de données, rechercher des clés primaires, etc. Plus loin dans cette procédure pas à pas, nous allons examiner comment vous pouvez remplacer ces conventions.
5. Gestion des modifications du modèle
Maintenant, il est temps d’apporter des modifications à notre modèle, lorsque nous effectuons ces modifications, nous devons également mettre à jour le schéma de base de données. Pour ce faire, nous allons utiliser une fonctionnalité appelée Migrations Code First ou Migrations pour court.
Les migrations nous permettent d’avoir un ensemble ordonné d’étapes qui décrivent comment mettre à niveau (et rétrograder) notre schéma de base de données. Chacune de ces étapes, appelée migration, contient du code qui décrit les modifications à appliquer.
La première étape consiste à activer Migrations Code First pour notre BlogContext.
Outils -> Gestionnaire de package de bibliothèque -> Console gestionnaire de package
Exécutez la commande Enable-Migrations dans la Console du Gestionnaire de Package
Un nouveau dossier Migrations a été ajouté à notre projet qui contient deux éléments :
- Configuration.cs : ce fichier contient les paramètres que migrations utiliseront pour migrer BlogsContext. Nous n’avons pas besoin de modifier quoi que ce soit pour cette procédure pas à pas, mais voici où vous pouvez spécifier des données initiales, inscrire des fournisseurs pour d’autres bases de données, modifier l’espace de noms généré dans etc.
- <timestamp>_InitialCreate.cs : il s’agit de votre première migration, il représente les modifications qui ont déjà été appliquées à la base de données pour le faire passer d’une base de données vide à une base de données qui inclut les tables Blogs et Posts. Bien que nous puissions créer automatiquement ces tables pour nous, maintenant que nous avons opté pour les migrations qu’ils ont été convertis en migration. Code First a également enregistré dans notre base de données locale que cette migration a déjà été appliquée. L’horodatage sur le nom de fichier est utilisé à des fins de classement.
Nous allons maintenant apporter une modification à notre modèle, ajouter une propriété Url à la classe Blog :
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public virtual List<Post> Posts { get; set; }
}
- Exécutez la commande AddUrl AddUrl de addurl dans la console du Gestionnaire de package. La commande Add-Migration vérifie les modifications depuis votre dernière migration et génère une nouvelle migration avec toutes les modifications trouvées. Nous pouvons donner un nom aux migrations; dans ce cas, nous appelons la migration « AddUrl ». Le code généré indique que nous devons ajouter une colonne Url, qui peut contenir des données de chaîne, à la dbo. Table blogs. Si nécessaire, nous pourrions modifier le code échafaudé, mais cela n’est pas obligatoire dans ce cas.
namespace CodeFirstNewDatabaseSample.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class AddUrl : DbMigration
{
public override void Up()
{
AddColumn("dbo.Blogs", "Url", c => c.String());
}
public override void Down()
{
DropColumn("dbo.Blogs", "Url");
}
}
}
- Exécutez la commande Update-Database dans la console du Gestionnaire de package. Cette commande applique toutes les migrations en attente à la base de données. Notre migration InitialCreate a déjà été appliquée afin que les migrations s’appliquent simplement à notre nouvelle migration AddUrl. Conseil : vous pouvez utiliser le commutateur –Verbose lors de l’appel de Update-Database pour voir le SQL en cours d’exécution sur la base de données.
La nouvelle colonne Url est désormais ajoutée à la table Blogs dans la base de données :
6. Annotations de données
Jusqu’à présent, nous avons simplement laissé EF découvrir le modèle à l’aide de ses conventions par défaut, mais il y aura des moments où nos classes ne suivent pas les conventions et que nous devons être en mesure d’effectuer une configuration supplémentaire. Il existe deux options pour cela; Nous allons examiner les annotations de données dans cette section, puis l’API Fluent dans la section suivante.
- Ajout d’une classe Utilisateur à notre modèle
public class User
{
public string Username { get; set; }
public string DisplayName { get; set; }
}
- Nous devons également ajouter un ensemble à notre contexte dérivé
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<User> Users { get; set; }
}
- Si nous avons essayé d’ajouter une migration, nous obtenons une erreur indiquant que « EntityType 'User' n’a pas de clé définie. Définissez la clé de ce EntityType. » étant donné qu’EF n’a aucun moyen de savoir que le nom d’utilisateur doit être la clé primaire de l’utilisateur.
- Nous allons maintenant utiliser des annotations de données pour ajouter une instruction using en haut de Program.cs
using System.ComponentModel.DataAnnotations;
- Annotez maintenant la propriété Username pour identifier qu’il s’agit de la clé primaire
public class User
{
[Key]
public string Username { get; set; }
public string DisplayName { get; set; }
}
- Utilisez la commande Add-Migration AddUser pour générer une génération automatique d’une migration pour appliquer ces modifications à la base de données
- Exécutez la commande Update-Database pour appliquer la nouvelle migration à la base de données
La nouvelle table est maintenant ajoutée à la base de données :
La liste complète des annotations prises en charge par EF est la suivante :
- KeyAttribute
- StringLengthAttribute
- MaxLengthAttribute
- ConcurrencyCheckAttribute
- RequiredAttribute
- TimestampAttribute
- ComplexTypeAttribute
- ColumnAttribute
- TableAttribute
- InversePropertyAttribute
- ForeignKeyAttribute
- DatabaseGeneratedAttribute
- NotMappedAttribute
7. API Fluent
Dans la section précédente, nous avons examiné l’utilisation des annotations de données pour compléter ou remplacer ce qui a été détecté par convention. L’autre façon de configurer le modèle consiste à utiliser l’API Code First Fluent.
La plupart des configurations de modèle peuvent être effectuées à l’aide d’annotations de données simples. L’API Fluent est un moyen plus avancé de spécifier la configuration du modèle qui couvre tout ce que les annotations de données peuvent faire en plus d’une configuration plus avancée non possible avec des annotations de données. Les annotations de données et l’API Fluent peuvent être utilisées ensemble.
Pour accéder à l’API Fluent, vous remplacez la méthode OnModelCreating dans DbContext. Supposons que nous voulions renommer la colonne dans laquelle User.DisplayName est stocké dans display_name.
- Remplacez la méthode OnModelCreating sur BlogsContext par le code suivant
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.Property(u => u.DisplayName)
.HasColumnName("display_name");
}
}
- Utilisez la commande Add-Migration ChangeDisplayName pour générer une structure de migration pour appliquer ces modifications à la base de données.
- Exécutez la commande Update-Database pour appliquer la nouvelle migration à la base de données.
La colonne DisplayName est maintenant renommée display_name :
Résumé
Dans cette procédure pas à pas, nous avons examiné le développement Code First à l’aide d’une nouvelle base de données. Nous avons défini un modèle à l’aide de classes, puis utilisé ce modèle pour créer une base de données et stocker et récupérer des données. Une fois la base de données créée, nous avons utilisé Migrations Code First pour modifier le schéma à mesure que notre modèle a évolué. Nous avons également vu comment configurer un modèle à l’aide d’annotations de données et de l’API Fluent.