added ex_042_010_SinglePropertyNavigation_conventions; need to write the ReadMe file

EFCore3_Reforged
Marc CHEVALDONNE 6 years ago
parent d1c05cb9f1
commit 19a358e2f4

@ -572,6 +572,11 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_009_DataSeeding", "p08_BDD_EntityFramework\ex_042_009_DataSeeding\ex_042_009_DataSeeding.csproj", "{B5CEC904-1475-4215-A20A-01BDD219AE25}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04. Relationships", "04. Relationships", "{C7672736-AA73-4B7E-B5C6-A7A984216372}"
ProjectSection(SolutionItems) = preProject
p08_BDD_EntityFramework\Relationships.md = p08_BDD_EntityFramework\Relationships.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ex_042_010_SinglePropertyNavigation_conventions", "p08_BDD_EntityFramework\ex_042_010_SinglePropertyNavigation_conventions\ex_042_010_SinglePropertyNavigation_conventions.csproj", "{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -4729,6 +4734,26 @@ Global
{B5CEC904-1475-4215-A20A-01BDD219AE25}.Release|x64.Build.0 = Release|Any CPU
{B5CEC904-1475-4215-A20A-01BDD219AE25}.Release|x86.ActiveCfg = Release|Any CPU
{B5CEC904-1475-4215-A20A-01BDD219AE25}.Release|x86.Build.0 = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|ARM.Build.0 = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|ARM64.Build.0 = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|x64.ActiveCfg = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|x64.Build.0 = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|x86.ActiveCfg = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Debug|x86.Build.0 = Debug|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|Any CPU.Build.0 = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|ARM.ActiveCfg = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|ARM.Build.0 = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|ARM64.ActiveCfg = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|ARM64.Build.0 = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|x64.ActiveCfg = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|x64.Build.0 = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|x86.ActiveCfg = Release|Any CPU
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -4999,6 +5024,7 @@ Global
{2249C4B0-563D-44C8-AAA5-C8366A8F509C} = {56C5A51B-16E9-4F93-9C32-8F91710391E8}
{B5CEC904-1475-4215-A20A-01BDD219AE25} = {78374D80-5BE7-425D-BE62-AD8F26491112}
{C7672736-AA73-4B7E-B5C6-A7A984216372} = {55E00151-58A6-4E7D-9457-0BB8213B82F5}
{0D750BE3-0B5C-433C-A3A2-B70F390B4E93} = {C7672736-AA73-4B7E-B5C6-A7A984216372}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8D31C3AE-36FF-4667-A2A7-0E670245A59E}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace ex_042_010_SinglePropertyNavigation_conventions
{
public class Information
{
public int InformationId { get; set; }
public string MadeBy { get; set; }
public string MadeIn { get; set; }
}
}

@ -0,0 +1,49 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ex_042_010_SinglePropertyNavigation_conventions
{
public class Nounours
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid UniqueId
{
get; set;
}
public string Nom
{
get;
set;
}
[Column("Naissance", TypeName = "date")]
public DateTime DateDeNaissance
{
get;
set;
}
public int NbPoils
{
get;
set;
}
public Information Information
{
get; set;
}
//public int InformationId
//{ get; set; }
public override string ToString()
{
return $"{UniqueId}: {Nom} ({DateDeNaissance:dd/MM/yyyy}, {NbPoils} poils, fait à {Information.MadeIn} par {Information.MadeBy})";
}
}
}

@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;
namespace ex_042_010_SinglePropertyNavigation_conventions
{
class NounoursDBEntities : DbContext
{
public virtual DbSet<Nounours> NounoursSet { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite($"Data Source=ex_042_010_SinglePropertyNavigation_conventions.Nounours.db");
}
}
}

@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using System;
namespace ex_042_010_SinglePropertyNavigation_conventions
{
class NounoursDBEntitiesWithStub : NounoursDBEntities
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var info1 = new Information { InformationId = 1, MadeBy = "George Lucas", MadeIn = "Kashyyyk" };
var info2 = new Information { InformationId = 2, MadeBy = "George Lucas", MadeIn = "Dagobah" };
var info3 = new Information { InformationId = 3, MadeBy = "George Lucas", MadeIn = "Lune forestière d'Endor" };
modelBuilder.Entity<Information>().HasData(info1, info2, info3);
modelBuilder.Entity<Nounours>().Property<int>("InformationId");
modelBuilder.Entity<Nounours>().HasData(
new { UniqueId = Guid.Parse("{4422C524-B2CB-43EF-8263-990C3CEA7CAE}"), Nom = "Chewbacca", DateDeNaissance = new DateTime(1977, 5, 27), NbPoils = 1234567, InformationId = 1 },
new { UniqueId = Guid.Parse("{A4F84D92-C20F-4F2D-B3F9-CA00EF556E72}"), Nom = "Yoda", DateDeNaissance = new DateTime(1980, 5, 21), NbPoils = 3, InformationId = 2 },
new { UniqueId = Guid.Parse("{AE5FE535-F041-445E-B570-28B75BC78CB9}"), Nom = "Ewok", DateDeNaissance = new DateTime(1983, 5, 25), NbPoils = 3456789, InformationId = 3 }
);
}
}
}

@ -0,0 +1,45 @@
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using static System.Console;
namespace ex_042_010_SinglePropertyNavigation_conventions
{
class Program
{
static void Main(string[] args)
{
OutputEncoding = System.Text.Encoding.UTF8;
var info1 = new Information { MadeBy = "George Lucas", MadeIn = "Kashyyyk" };
var info2 = new Information { MadeBy = "George Lucas", MadeIn = "Dagobah" };
var info3 = new Information { MadeBy = "George Lucas", MadeIn = "Lune forestière d'Endor" };
var n1 = new Nounours { Nom = "Chewbacca", DateDeNaissance = new DateTime(1977, 5, 27), NbPoils = 1234567, Information = info1 };
var n2 = new Nounours { Nom = "Yoda", DateDeNaissance = new DateTime(1980, 5, 21), NbPoils = 3, Information = info2 };
var n3 = new Nounours { Nom = "Ewok", DateDeNaissance = new DateTime(1983, 5, 25), NbPoils = 3456789, Information = info3 };
try
{
using (NounoursDBEntities db = new NounoursDBEntities())
{
WriteLine("Contenu de la base :");
foreach (var n in db.NounoursSet.Include(n => n.Information))
{
WriteLine($"\t{n}");
}
}
}
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,122 @@
# ex_042_010_SinglePropertyNavigation_conventions
**TO BE WRITTEN**
*17/01/2020 &sdot; Marc Chevaldonné*
---
Cet exemple montre comment réaliser une navigation entre deux entités avec une propriété simple (sens unique) avec Entity Framework Core.
---
## Comment est construit cet exemple ?
* Le projet est de type .NET Core
* Il contient quatre classes :
* ```Nounours```
* ```Information```
* ```NounoursDBEntities```
* ```NounoursDBEntitiesWithStub```
Le contenu des classes ```Nounours``` et ```NounoursDBEntities``` correspond à ce qui a été vu dans les exemples précédents. Seule la classe ```NounoursDBEntitiesWithStub``` sera donc expliquée ici.
### La classe ```NounoursDBEntitiesWithStub```
* ```NounoursDBEntitiesWithStub``` est une classe fille de ```NounoursDBEntites```.
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
using Microsoft.EntityFrameworkCore;
using System;
namespace ex_042_009_DataSeeding
{
class NounoursDBEntitiesWithStub : NounoursDBEntities
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Nounours>().HasData(
new Nounours { UniqueId = Guid.Parse("{4422C524-B2CB-43EF-8263-990C3CEA7CAE}"), Nom = "Chewbacca", DateDeNaissance = new DateTime(1977, 5, 27), NbPoils = 1234567 },
new Nounours { UniqueId = Guid.Parse("{A4F84D92-C20F-4F2D-B3F9-CA00EF556E72}"), Nom = "Yoda", DateDeNaissance = new DateTime(1980, 5, 21), NbPoils = 3 },
new Nounours { UniqueId = Guid.Parse("{AE5FE535-F041-445E-B570-28B75BC78CB9}"), Nom = "Ewok", DateDeNaissance = new DateTime(1983, 5, 25), NbPoils = 3456789 }
);
}
}
}
```
* __Note importante__ : remarquez que la création des instances d'entités donne aussi l'```UniqueId``` puisqu'il ne s'agit pas d'un ajout "classique" dans la base mais la table est créée avec ces instances.
* __Note importante__ : l'utilisation de ```UniqueId``` vous permettra d'ajouter des entités liées dans le Stub.
* __Explication__ : l'utilisaiton de ```HasData``` dans ```OnModelCreating``` fait que vos données stubbées feront parties de la migration : rien à voir avec un ajout depuis votre appli consommatrice.
* __Note__ : souvent, on en profite pour réécrire également ```OnConfiguring``` afin de changer de fournisseur (pour prendre par exemple un *SQLite in memory* puisque ce contexte stubbé est voué à être utilisé par des tests).
* Elle est ensuite utilisée dans ```Program``` pour remplir la base de manière tout à fait classique et ne nécessite aucun appel supplémentaire.
```csharp
using (NounoursDBEntities db = new NounoursDBEntitiesWithStub())
{
WriteLine("Contenu de la base :");
foreach (var n in db.NounoursSet)
{
WriteLine($"\t{n}");
}
}
```
## 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*, 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_009_DataSeeding
```
*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 migration_ex_042_009
```
* Création de la table :
```
dotnet ef database update
```
* Génération et exécution
Vous pouvez maintenant générer et exécuter l'exemple **ex_042_009_DataSeeding**.
* Le résultat de l'exécution va ressembler à :
```
Contenu de la base :
ae5fe535-f041-445e-b570-28b75bc78cb9: Ewok (25/05/1983, 3456789 poils)
4422c524-b2cb-43ef-8263-990c3cea7cae: Chewbacca (27/05/1977, 1234567 poils)
a4f84d92-c20f-4f2d-b3f9-ca00ef556e72: Yoda (21/05/1980, 3 poils)
```
* Comment vérifier le contenu des bases de données SQL Server ?
Vous pouvez vérifier le contenu de votre base en utilisant l'*Explorateur d'objets SQL Server*.
* Pour cela, allez dans le menu *Affichage* puis *Explorateur d'objets SQL Server*.
<img src="../ex_041_001_ConnectionStrings/readmefiles/sqlserver_01.png" width="500"/>
* Déployez dans l'*Explorateur d'objets SQL Server* :
* *SQL Server*,
* puis *(localdb)\MSSQLLocalDB ...*,
* puis *Bases de données*
* puis celle portant le nom de votre migration, dans mon cas : *ex_042_009_DataSeeding.Nounours.mdf*
* puis *Tables*
* Faites un clic droit sur la table *dbo.Nounours* puis choisissez *Afficher les données*
<img src="../ex_041_001_ConnectionStrings/readmefiles/sqlserver_02.png" width="460"/>
* Vous devriez maintenant pouvoir voir les données suivantes dans le tableau :
|UniqueId |Nom|Naissance|NbPoils
|---|---|---|---
|ae5fe535-f041-445e-b570-28b75bc78cb9|Ewok|25/05/1983|3456789
|4422c524-b2cb-43ef-8263-990c3cea7cae|Chewbacca|27/05/1977|1234567
|a4f84d92-c20f-4f2d-b3f9-ca00ef556e72|Yoda|21/05/1980|3

@ -0,0 +1,13 @@
<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