begun ex_042_013

EFCore3_Reforged
Marc CHEVALDONNE 5 years ago
parent bd505a2981
commit 15f4cc64e1

@ -580,6 +580,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_011_SinglePropertyNa
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_012_OneToOne_conventions", "p08_BDD_EntityFramework\ex_042_012_OneToOne_conventions\ex_042_012_OneToOne_conventions.csproj", "{762C349D-5685-43FA-A077-2F3BDD07C898}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ex_042_013_OneToOne_FluentAPI", "p08_BDD_EntityFramework\ex_042_013_OneToOne_FluentAPI\ex_042_013_OneToOne_FluentAPI.csproj", "{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -4776,6 +4778,26 @@ Global
{762C349D-5685-43FA-A077-2F3BDD07C898}.Release|x64.Build.0 = Release|Any CPU
{762C349D-5685-43FA-A077-2F3BDD07C898}.Release|x86.ActiveCfg = Release|Any CPU
{762C349D-5685-43FA-A077-2F3BDD07C898}.Release|x86.Build.0 = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|ARM.ActiveCfg = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|ARM.Build.0 = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|ARM64.Build.0 = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|x64.ActiveCfg = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|x64.Build.0 = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|x86.ActiveCfg = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Debug|x86.Build.0 = Debug|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|Any CPU.Build.0 = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|ARM.ActiveCfg = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|ARM.Build.0 = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|ARM64.ActiveCfg = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|ARM64.Build.0 = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|x64.ActiveCfg = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|x64.Build.0 = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|x86.ActiveCfg = Release|Any CPU
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -5048,6 +5070,7 @@ Global
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93} = {C7672736-AA73-4B7E-B5C6-A7A984216372}
{CCC912CB-2962-441E-AB6B-97B0CB32AF11} = {C7672736-AA73-4B7E-B5C6-A7A984216372}
{762C349D-5685-43FA-A077-2F3BDD07C898} = {C7672736-AA73-4B7E-B5C6-A7A984216372}
{ADF1001A-AF43-4D6E-9D4A-B0C26E4E19D5} = {C7672736-AA73-4B7E-B5C6-A7A984216372}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8D31C3AE-36FF-4667-A2A7-0E670245A59E}

@ -1,5 +1,5 @@
# Entity Framework Core 3.0
*19/01/2020 ⋅ Marc Chevaldonné*
*20/01/2020 ⋅ Marc Chevaldonné*
---
Entity Framework (EF) Core est un ORM (Object-Relational Mapper) qui permet aux développeurs .NET de gérer de manière simple, légère et extensible, des bases de données.

@ -1,15 +1,4 @@
// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
// marc.chevaldonne.free.fr
//
// Module : NounoursDBEntities.cs
// Author : Marc Chevaldonné
// Creation date : 2016-10-18
//
// ========================================================================
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace ex_042_012_OneToOne_conventions
{

@ -1,15 +1,4 @@
// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
// marc.chevaldonne.free.fr
//
// Module : Program.cs
// Author : Marc Chevaldonné
// Creation date : 2016-10-18
//
// ========================================================================
using Microsoft.Data.Sqlite;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System;
using static System.Console;

@ -0,0 +1,31 @@
using System;
namespace ex_042_013_OneToOne_FluentAPI
{
/// <summary>
/// CarnetDeSante est une classe POCO, i.e. Plain Old CLR Object
/// Elle a une relation 1-1 avec la classe Nounours via la propriété Owner.
/// </summary>
public class CarnetDeSante
{
public int UniqueId
{
get; set;
}
public DateTime LastModified
{
get; set;
}
public Nounours Owner
{
get; set;
}
public override string ToString()
{
return $"{UniqueId} : carnet de {Owner.Nom}, modifié la dernière fois le {LastModified.ToString("d")}";
}
}
}

@ -0,0 +1,41 @@
using System;
namespace ex_042_013_OneToOne_FluentAPI
{
/// <summary>
/// Nounours est une classe POCO, i.e. Plain Old CLR Object.
/// Elle a une relation 1-1 avec la classe CarnetDeSante via la propriété Carnet.
public class Nounours
{
public int UniqueId
{
get; set;
}
public CarnetDeSante Carnet { get; set; }
public string Nom
{
get;
set;
}
public DateTime DateDeNaissance
{
get;
set;
}
public int NbPoils
{
get;
set;
}
public override string ToString()
{
return $"{UniqueId}: {Nom} ({DateDeNaissance:dd/MM/yyyy}, {NbPoils} poils)";
}
}
}

@ -0,0 +1,53 @@
using Microsoft.EntityFrameworkCore;
namespace ex_042_013_OneToOne_FluentAPI
{
/// <summary>
/// La classe qui dérive de DbContext est celle qui permettra de faire les opérations CRUD sur le modèle.
/// Cette classe contient deux DbSet<T> pour permettre de réaliser des opérations CRUD sur les types T, ici Nounours et CarnetDeSante.
/// </summary>
public class NounoursDBEntities : DbContext
{
public DbSet<Nounours> NounoursSet { get; set; }
public DbSet<CarnetDeSante> Carnets { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite($"Data Source=ex_042_013_OneToOne_FluentAPI.Nounours.db");
}
/// <summary>
/// méthode appelée lors de la création du modèle.
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//création de la table TableNounours
modelBuilder.Entity<Nounours>().ToTable("TableNounours"); //nom de la table
modelBuilder.Entity<Nounours>().HasKey(n => n.UniqueId); //définition de la clé primaire
modelBuilder.Entity<Nounours>().Property(n => n.UniqueId)
.ValueGeneratedOnAdd(); //définition du mode de génération de la clé : génération à l'insertion
modelBuilder.Entity<Nounours>().Property(n => n.Nom).IsRequired()
.HasMaxLength(256); //définition de la colonne Nom
modelBuilder.Entity<Nounours>().Property(n => n.DateDeNaissance).HasColumnName("Naissance").HasColumnType("date"); //changement du nom de la colonne Naissance
//création de la table "Carnets"
modelBuilder.Entity<CarnetDeSante>().ToTable("Carnets"); // nom de la table
modelBuilder.Entity<CarnetDeSante>().HasKey(c => c.UniqueId); //définition de la clé primaire
//modelBuilder.Entity<CarnetDeSante>().Property(c => c.Owner).IsRequired();
modelBuilder.Entity<CarnetDeSante>().Property(c => c.UniqueId)
.ValueGeneratedNever(); // définition du mode de génération de la clé : pas de génération automatique
//note : la colonne LastModified n'est pas touchée : utilisation des conventions EF
//on précise qu'il y a une relation entre CarnetDeSante et Nounours
modelBuilder.Entity<Nounours>() //l'entité Nounours...
.HasOne(n => n.Carnet) //a une propriété obligatoire Carnet...
.WithOne(c => c.Owner) //reliée à la propriété Owner du Carnet...
.HasForeignKey<CarnetDeSante>(c => c.UniqueId);//dont la propriété UniqueId est une Foreign Key
//remplace la ForeignKey
base.OnModelCreating(modelBuilder);
}
}
}

@ -0,0 +1,71 @@
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System;
using static System.Console;
namespace ex_042_013_OneToOne_FluentAPI
{
public class Program
{
/// <summary>
/// Cet exemple montre comment construire une relation 1-1 dans la base de données en utilisant les conventions de nommage Entity Framework.
/// </summary>
static void Main(string[] args)
{
OutputEncoding = System.Text.Encoding.UTF8;
try
{
using (NounoursDBEntities db = new NounoursDBEntities())
{
WriteLine("Contenu de la base (nounours) : ");
foreach (var n in db.NounoursSet.Include(n => n.Carnet))
{
WriteLine($"\t{n}, LastModified: {n.Carnet.LastModified.ToString("d")}");
}
WriteLine("Contenu de la base (carnets de santé) : ");
foreach (var c in db.Carnets)
{
WriteLine($"\t{c}");
}
WriteLine("\nAjout d'un nounours et de son carnet de santé\n");
Nounours porg = new Nounours { Nom = "Porg", DateDeNaissance = new DateTime(2017, 7, 19), NbPoils = 123 };
CarnetDeSante carnetPorg = new CarnetDeSante { LastModified = DateTime.Now, Owner = porg };
porg.Carnet = carnetPorg;
db.AddRange(porg, carnetPorg);
db.SaveChanges();
}
using (NounoursDBEntities db = new NounoursDBEntities())
{
WriteLine("Contenu de la base (nounours) : ");
foreach (var n in db.NounoursSet.Include(n => n.Carnet))
{
WriteLine($"\t{n}, LastModified: {n.Carnet.LastModified.ToString("d")}");
}
WriteLine("Contenu de la base (carnets de santé) : ");
foreach (var c in db.Carnets)
{
WriteLine($"\t{c}");
}
}
}
catch (NotImplementedException exception)
{
WriteLine(exception.Message);
}
catch (SqliteException)
{
WriteLine("Votre base de données n'existe pas. C'est peut-être la première fois que vous exécutez cet exemple.");
WriteLine("Pour créer la base de données, suivez les instructions données dans le fichier ReadMe.md associé à cet exemple.");
}
ReadLine();
}
}
}

@ -0,0 +1,216 @@
# ex_042_012_OneToOne_conventions
*20/01/2020 &sdot; Marc Chevaldonné*
---
Cet exemple montre comment réaliser une relation *One To One* entre deux entités avec *Entity Framework Core* et l'*annotation de données*.
Une version équivalente réalisée avec la *Fluent API* est disponible dans l'exemple
[**ex_042_013 : One To One with Fluent API**](../ex_042_013_OneToOne_FluentAPI)
---
## Comment est construit cet exemple ?
* Le projet est de type .NET Core
* Il contient quatre classes :
* ```Nounours```
* ```CarnetDeSante```
* ```NounoursDBEntities```
* ```StubbedContext```
### Les classes entités : ```Nounours``` et ```CarnetDeSante```
Un ```Nounours``` contient différentes propriétés (```Nom```, ```DateDeNaissance```, ```NbPoils```) dont ```Carnet``` de type ```CarnetDeSante```.
Un ```CarnetDeSante``` possède une propriété de type ```DateTime``` (```LastModified```), et une propriété ```Owner``` de type ```Nounours```.
On a donc bien une relation *One To One* puisqu'un ```Nounours``` possède un ```CarnetDeSante``` et qu'un ```CarnetDeSante``` possède un ```Nounours```.
<img src="./readme_files/ex_042_012_classDiagram.svg"/>
Ce qu'il faut noter :
* ```Nounours``` possède une association vers ```CarnetDeSante```
```csharp
public CarnetDeSante Carnet { get; set; }
```
* ```CarnetDeSante``` possède une association vers ```Nounours```
```csharp
public Nounours Owner { get; set; }
```
* ```Nounours``` possède un identifiant unique (qui peut être utilisé par convention d'écriture ou _annotation de données_) : ```[Key]```.
* Cet identifiant est généré par la base : ```[DatabaseGenerated(DatabaseGeneratedOption.Identity)]```.
* ```CarnetDeSante``` possède un identifiant unique (qui peut être utilisé par convention d'écriture ou _annotation de données_) : ```[Key]```.
* Cet identifiant fait référence à une clé étrangère qui est la clé primaire associée à l'entité pointée par sa propriété ```Owner``` : ```ForeignKey("Owner")```.
```csharp
[Key, ForeignKey("Owner")]
public int UniqueId
{
get; set;
}
```
* En conséquence, l'identifiant unique ```UniqueId``` de ```CarnetDeSante``` aura la même valeur que l'```UniqueId``` d'une entité ```Nounours```.
### La classe ```NounoursDBEntities```
* Comme dans les exemples précédents, ```NounoursDBEntities``` dérive de ```DbContext```.
* ```NounoursDBEntities``` déclare deux ```DbSet``` : un de ```Nounours``` et l'autre de ```CarnetDeSante```.
```csharp
public DbSet<Nounours> NounoursSet { get; set; }
public DbSet<CarnetDeSante> Carnets { get; set; }
```
##### Quelques explications supplémentaires :
Pour pouvoir relier une entité ```Nounours``` à une entité ```CarnetDeSante``` de manière bidirectionnelle, les propriétés ```Nounours.Carnet``` et ```CarnetDeSante.Owner``` sont suffisantes, à condition qu'une clé étrangère soit déclarée et utilisée.
C'est le cas grâce à l'annotation de données ```ForeignKey("Owner")``` qui s'occupe de définir de quelle manière les deux entités sont reliées.
### La classe ```StubbedContext```
* ```StubbedContext``` est une classe fille de ```NounoursDBEntities```.
Son rôle est de proposer un Stub en plus de ce que sait déjà faire sa classe mère. Elle ne sera donc utilisée que pour des tests unitaires ou fonctionnels.
En conséquence, elle reprend tout ce que fait sa classe mère et ne change que la méthode ```OnModelCreating``` qui appelle la méthode de la classe mère puis ajoute des instances d'entités, grâce à la méthode d'extension ```HasData```.
```csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<CarnetDeSante>().HasData(
new CarnetDeSante { UniqueId=1, LastModified = DateTime.Today },
new CarnetDeSante { UniqueId=2, LastModified = new DateTime(1980, 5, 21) },
new CarnetDeSante { UniqueId=3, LastModified = new DateTime(1983, 5, 25) }
);
modelBuilder.Entity<Nounours>().HasData(
new Nounours { UniqueId=1, Nom = "Chewbacca", DateDeNaissance = new DateTime(1977, 5, 27), NbPoils = 1234567 },
new Nounours { UniqueId=2, Nom = "Yoda", DateDeNaissance = new DateTime(1980, 5, 21), NbPoils = 3 },
new Nounours { UniqueId=3, Nom = "Ewok", DateDeNaissance = new DateTime(1983, 5, 25), NbPoils = 3456789 }
);
}
```
* Remarquez que __À AUCUN MOMENT__ nous ne précisons les valeurs des propriétés ```Owner``` de ```CarnetDeSante``` et ```Carnet``` de ```Nounours```.
Le simple fait d'utiliser la même clé (propriétés ```UniqueId```) est suffisant puisque celle de ```CarnetDeSante``` est une clé étrangère.
* Notez que ce ne sera pas le cas lors d'une utilisation *classique* de nos classes (ajout, modification...). Nous ne donnerons plus les identifiants directement mais les références des propriétés ```Carnet``` et ```Owner```.
### La classe ```Program```
* La classe ```StubbedContext``` est ensuite indirectement utilisée dans ```Program``` pour remplir la base de manière tout à fait classique et ne nécessite aucun appel supplémentaire : ceci est fait lors de la migration et la création de la base.
* On affiche tout d'abord le contenu de la base (c'est-à-dire rien ou d'anciennes données si la migration est faite à partir de ```NounoursDBEntites```) ou le stub (si la migration est faite à partir de ```StubbedContext```).
*Notez l'utilisation d'```Include``` dans ```db.NounoursSet.Include(n => n.Carnet)``` sinon, les ```CarnetDeSante``` ne sont pas chargés. ```Include``` n'est pas utilisé ensuite dans ```db.Carnets``` car les ```Nounours``` ont déjà été chargés depuis la connexion. Mais on aurait pu faire les accès dans l'autre sens et dans ce cas d'abord ```db.Carnets.Include(c => c.Owner)``` puis simplement ```db.NounoursSet```.*
```csharp
using (NounoursDBEntities db = new NounoursDBEntities())
{
WriteLine("Contenu de la base (nounours) : ");
foreach (var n in db.NounoursSet.Include(n => n.Carnet))
{
WriteLine($"\t{n}, LastModified: {n.Carnet.LastModified.ToString("d")}");
}
WriteLine("Contenu de la base (carnets de santé) : ");
foreach (var c in db.Carnets)
{
WriteLine($"\t{c}");
}
//...
}
```
* La suite de l'exemple ajoute un nouveau ```Nounours``` et son ```CarnetDeSante``` puis affiche le contenu de la base de données.
```csharp
using (NounoursDBEntities db = new NounoursDBEntities())
{
//...
WriteLine("\nAjout d'un nounours et de son carnet de santé\n");
Nounours porg = new Nounours { Nom = "Porg", DateDeNaissance = new DateTime(2017, 7, 19), NbPoils = 123 };
CarnetDeSante carnetPorg = new CarnetDeSante { LastModified = DateTime.Now, Owner = porg };
porg.Carnet = carnetPorg;
db.AddRange(porg, carnetPorg);
db.SaveChanges();
}
```
```csharp
using (NounoursDBEntities db = new NounoursDBEntities())
{
WriteLine("Contenu de la base (nounours) : ");
foreach (var n in db.NounoursSet.Include(n => n.Carnet))
{
WriteLine($"\t{n}, LastModified: {n.Carnet.LastModified.ToString("d")}");
}
WriteLine("Contenu de la base (carnets de santé) : ");
foreach (var c in db.Carnets)
{
WriteLine($"\t{c}");
}
}
```
## Comment exécuter cet exemple ?
Pour tester cette application, n'oubliez pas les commandes comme présentées dans l'exemple ex_041_001 : pour générer l'exemple, il vous faut d'abord préparer les migrations et les tables.
* Ouvrez la *Console du Gestionnaire de package* sous Windows ou le *Terminal* sous MacOSX, pour cela, dirigez-vous dans le menu *Outils*, puis *Gestionnaire de package NuGet*, puis *Console du Gestionnaire de package*.
* Dans la console que vous venez d'ouvrir, déplacez-vous dans le dossier du projet .NET Core, ici :
```
cd .\p08_BDD_EntityFramework\ex_042_012_OneToOne_conventions
```
*Note*:
si vous n'avez pas installé correctement EntityFrameworkCore, il vous faudra peut-être utiliser également :
* ```dotnet tool install --global dotnet-ef``` si vous utilisez la dernière version de .NET Core (3.1 aujourd'hui),
* ```dotnet tool install --global dotnet-ef --version 3.0.0``` si vous vous utiliser spécifiquement .NET Core 3.0.
* Migration :
```
dotnet ef migrations add ex_042_012 --context StubbedContext
```
* Création de la table :
```
dotnet ef database update --context StubbedContext
```
* Génération et exécution
Vous pouvez maintenant générer et exécuter l'exemple **ex_042_012_OneToOne_conventions**.
* Le résultat de l'exécution va ressembler à :
```
Contenu de la base (nounours) :
1: Chewbacca (27/05/1977, 1234567 poils), LastModified: 20/01/2020
2: Yoda (21/05/1980, 3 poils), LastModified: 21/05/1980
3: Ewok (25/05/1983, 3456789 poils), LastModified: 25/05/1983
Contenu de la base (carnets de santé) :
1 : carnet de Chewbacca, modifié la dernière fois le 20/01/2020
2 : carnet de Yoda, modifié la dernière fois le 21/05/1980
3 : carnet de Ewok, modifié la dernière fois le 25/05/1983
Ajout d'un nounours et de son carnet de santé
Contenu de la base (nounours) :
1: Chewbacca (27/05/1977, 1234567 poils), LastModified: 20/01/2020
2: Yoda (21/05/1980, 3 poils), LastModified: 21/05/1980
3: Ewok (25/05/1983, 3456789 poils), LastModified: 25/05/1983
4: Porg (19/07/2017, 123 poils), LastModified: 20/01/2020
Contenu de la base (carnets de santé) :
1 : carnet de Chewbacca, modifié la dernière fois le 20/01/2020
2 : carnet de Yoda, modifié la dernière fois le 21/05/1980
3 : carnet de Ewok, modifié la dernière fois le 25/05/1983
4 : carnet de Porg, modifié la dernière fois le 20/01/2020
```
*Note : l'identifiant du dernier ```Nounours``` sera vraisemblablement différent puisqu'il est créé par la base lors de l'insertion.*
## Comment exécuter cet exemple sans le stub ?
Il suffit de faire exactement comme dans le paragraphe précédent, mais en choisissant le contexte ```NounoursDBEntities``` à la place de ```StubbedContext``` :
```
dotnet ef migrations add ex_042_012 --context NounoursDBEntities
dotnet ef database update --context NounoursDBEntities
```
Lors de l'exécution, le résultat sera évidemment différent puisqu'il n'y aura pas les 3 nounours du stub.
## Comment vérifier quelles base et tables ont été créées et leur contenu ?
Pour vérifier le contenu de votre base SQLite, vous pouvez utiliser le programme *DB Browser* :
* Rendez-vous sur la page : https://sqlitebrowser.org/dl/ et téléchargez le programme *DB Browser*.
* Lancez *DB Browser for SQLite*
* Glissez-déposez au milieu de la fenêtre de *DB Browser for SQLite* le fichier *ex_042_012_OneToOne_conventions.Nounours.db* qui a été généré par l'exécution du programme et qui se trouve près de *ex_042_012_OneToOne_conventions.csproj*.
![DB Browser for SQLite](./readme_files/dbbrowser01.png)
* Choisissez ensuite l'onglet *Parcourir les données*
* Observez les résultats obtenus des deux tables
![DB Browser for SQLite](./readme_files/dbbrowser02.png)
![DB Browser for SQLite](./readme_files/dbbrowser03.png)

@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
namespace ex_042_013_OneToOne_FluentAPI
{
class StubbedContext : NounoursDBEntities
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<CarnetDeSante>().HasData(
new CarnetDeSante { UniqueId=1, LastModified = DateTime.Today },
new CarnetDeSante { UniqueId=2, LastModified = new DateTime(1980, 5, 21) },
new CarnetDeSante { UniqueId=3, LastModified = new DateTime(1983, 5, 25) }
);
modelBuilder.Entity<Nounours>().HasData(
new Nounours { UniqueId=1, Nom = "Chewbacca", DateDeNaissance = new DateTime(1977, 5, 27), NbPoils = 1234567 },
new Nounours { UniqueId=2, Nom = "Yoda", DateDeNaissance = new DateTime(1980, 5, 21), NbPoils = 3 },
new Nounours { UniqueId=3, Nom = "Ewok", DateDeNaissance = new DateTime(1983, 5, 25), NbPoils = 3456789 }
);
}
}
}

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<StartWorkingDirectory>$(MSBuildProjectDirectory)</StartWorkingDirectory>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SQLite" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0" />
</ItemGroup>
</Project>
Loading…
Cancel
Save