Archive

Posts Tagged ‘C# 6’

Entity Framework et C# 6 : Utilisation des propriétés automatiques en lecture seule au niveau de vos entités

Avec C# 6 nous avons vu l’apparition de pas mal d’améliorations au niveau de la syntaxe. Ces nouveautés syntaxiques sont souvent mises dans la catégorie sucre syntaxique et comme exemple nous avons la propriété automatique en lecture seule permettant d’avoir juste un accesseur Get et qu’il est possible d’assigner via le constructeur.

Supposons que nous ayons la classe ci-dessous utilisée comme entité Entity Framework :

public class Product
{
	[Key]
	public Guid Reference { get; private set; }

	public string Name { get; set; }

	public string Description { get; set; }

	public Product()
	{
		this.Reference = Guid.NewGuid();
	}
}

Avec un contexte très simple :

public class MyDbContext : DbContext
{
	public DbSet<Product> Products { get; set; }

	public MyDbContext() : base("name=MyDbContext")
	{
	}
}

Avec C# 6 et les propriétés automatiques en lecture seule nous pouvons changer la définition de la propriété Reference en supprimant le modificateur Set. D’ailleurs si vous utilisez Resharper, cet outil vous incitera à changer la syntaxe comme le montre la capture d’écran ci-dessous :

ReadonlyAutoProperty

Au final nous aurons le code suivant :

public class Product
{
	[Key]
	public Guid Reference { get; }

	public string Name { get; set; }

	public string Description { get; set; }

	public Product()
	{
		this.Reference = Guid.NewGuid();
	}
}

Sauf qu’avec cette dernière version de l’entité Product en essayant de mettre les fichiers de migrations de la base de données à jour via la commande suivante : add-migration ProductUpdated nous rencontrons l’erreur suivante dans le Package Manager Console :

EntityType ‘Product’ has no key defined. Define the key for this EntityType.
Products: EntityType: EntitySet ‘Products’ is based on type ‘Product’ that has no keys defined.

Bien que notre propriété est toujours décorée de l’attribut Key, l’entité Product est quand même considérée comme n’ayant pas défini une clé primaire d’après Entity Framework. Il faut se rappeler que la plomberie d’Entity Framework veut que toutes les propriétés définies au niveau de l’entité qui sont mappées à des colonnes d’une table de la base données soient définies avec un accesseur Get et un modificateur Set. Le modificateur doit être présent dans tous les cas même si sa visibilité est restreinte en utilisant le mot-clé private.

Ce n’est parce qu’on a une propriété automatique écrite avec la syntaxe { get; private set; } puis remplacée avec l’utilisation d’une propriété automatique en lecture seule { get; } que l’objectif initial reste inchangé et qu’un modificateur Set sera créé automatiquement une fois le code compilé. On peut le croire vu que l’assignation de la propriété existe toujours au niveau du constructeur.

Pour preuve la propriété Reference  définie en tant que propriété automatique avec { get; private set; } est générée comme suit en IL :

PrivateSet

La version IL de la propriété lorsqu’on utilise la propriété automatique en lecture seule avec la syntaxe C# 6 { get; } et avec toujours la présence de l’assignation de la propriété dans le constructeur :

Readonly auto-prop

Dans la dernière image on note l’absence d’un modificateur Set.

En conclusion, bien qu’on soit bien tenté par l’utilisation de la propriété automatique en lecture seule (surtout quand des outils comme ReSharper nous les proposent) on doit toujours se rappeler qu’Entity Framework a bien besoin de la présence d’un modificateur quelle que soit la visibilité de ce dernier pour les propriétés mappées aux tables de la base de données et ne manquera pas de vous le rappeler. Pour éviter à d’autres développeurs, qui seraient amenés à faire évoluer le modèle Entity Framework, de modifier toutes les propriétés { get; private set; } et les remplacer par { get; }, il faudra veiller à bien configurer les outils d’aide à la programmation.

Dans le cas de ReSharper, certaines propositions peuvent être désactivées au niveau du fichier comme dans l’image ci-dessous :

DisableReSharper

On peut aussi configurer la version de C# sur laquelle ReSharper doit se baser pour les différentes propositions en faisant F4 sur le projet concerné :

DisableReSharperProjectProperties

J’espère que ce billet vous a été utile 😉

%d blogueurs aiment cette page :