Les propriétés tenues dans Entity Framework 3

Une nouveauté que j’aime bien sont les propriétés tenues (owned properties) dans EF 3.

Elles permettent de simplifier un peu son modèle de données et ses tables dans certaines circonstances.

Donc un petit tuto!

Introduction

 

J’ai créé un projet de démo complet sur Github:

https://github.com/DeLeneMirouze/DemoEF3Owned

 

Si vous chargez le projet vous trouverez ceci:

 

On a en réalité 2 projets.

Le premier placé dans le répertoire TradiWay est un exemple sans utiliser les propriétés tenues. Le deuxième situé dans OwnedWay est identique, mais avec des propriétés tenues.

Vous remarquerez dans chaque cas le script de la base de données associées.

 

Dans OwnedWay il y a en fait 2 projets. Le premier est monté avec EF 3.0 et le suivant avec EF 3.1 (preview). Pourquoi celà?

Pour démontrer un bug présent dans EF 3.0 qui empêche de faire du INSERT. Ce bug est corrigé dans 3.1.

 

Un projet de quoi au juste?

Il est très simple, deux tables:

  • RESTAURANTS
  • ADDRESSES

 

On créée des restaurants que l’on associe à leurs adresses. Rien de compliqué.

Les projets sont des applications Console qui montre les opérations GET, INSERT, UPDATE, DELETE.

 

Un dernier point avant d’entrer dans le vif du sujet: j’utilise Bogus pour générer des datas sans efforts. Si Bogus vous intéresse j’ai fais un tuto ici:

https://amethyste16.wordpress.com/2019/09/26/creer-des-donnees-factices/

 

Méthode traditionnelle

Comment faisait t’on avant?

 

La visite comment dans nos bases de données qui ressemblent à ceci:

 

Deux tables avec chacune un ID. La table restaurant disposant d’une colonne IDADDRESS servent de clef étrangère vers la table ADDRESSES.

Côté .NET on a un modèle de données qui mappe directement ces tables.


public class Restaurant
{
   public int Id { get; set; }

   public string Name { get; set; }

   [Required]
   [ForeignKey("Address")]
   public int IdAddress { get; set; }

   public Address Address { get; set; }
}

 

On voit la déclaration d’une propriété de navigation Address, mais aussi l’ajout de IdAddress qui bien que facultative facilite bien la vie.

 

Comme les autres projets j’ai créé une classe RestaurantRepository qui implémente les méthodes GET, INSERT, UPDATE. Je vous laisserai la découvrir dans le code.

Jeton un coup d’œil à Main (la partie importante) qui est identique dans chaque projet:


Restaurant created = repository.Add(restaurant);
var newRestaurant = repository.Get(created.Id);

newRestaurant.Address.Number = "15";
repository.Update(newRestaurant);

repository.Delete(newRestaurant.Id);

 

Je créée un restaurant avec son adresse, je le retrouve, je modifie un de ses champs et je fais le ménage.

Effectuez ce code pas à pas en suivant son action depuis Microsoft SQL Server Management Studio.

 

Version avec les propriétés tenues

La version « Tradi » a surtout pour but de faciliter la compréhension sans entrer dans de longs développement.

 

Main est le même, par contre la base de données et le modèle sont un peu différents. Commençons par regarder les tables:

On remarque tout de suite que la table Addresses n’expose plus d’ID. Ce n’est pas nécessaire. Par contre il se trouve une clef étrangère vers Restaurant. J’y ai ajouté une contrainte: ON DELETE CASCADE

Cette opération n’est en rien intrinsèque aux propriétés tenues qui comme on le verra sont des propriétés tout ce qu’il y a de plus ordinaires.

Bien entendu le modèle objet C# s’ajuste en conséquence.

 

La partie intéressante se trouve dans la méthode OnModelCreating du DBContext:


protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Entity<Restaurant>()
      .OwnsOne(p => p.Address)
      .ToTable("Addresses");
}

 

Regardez l’extension OwnsOne, c’est elle qui définit Restaurant.Address comme propriété tenue.

A partir de ce moment Address se comporte comme une propriété de navigation ordinaire, sauf que l’on a plus besoin de s’encombrer des clefs étrangères. EF le fera pour nous.

La preuve est que le repository n’a pas besoin d’évoluer.

 

N’hésitez donc pas à tester le code proposé pour vérifier que ça fonctionne.

Laisser un commentaire