EF CORE 2.1 - les nouveautés, les annonces
Durant la Build, Andrew Peters et Diego Vega de Microsoft, nous ont présenté les nouveautés apportées par EF CORE 2.1 à travers la session "Entity Framework Core 2.1: Simple, Powerful Data Access for .NET". Vous aviez pu avoir un aperçu dans l'article d'Olivier traitant de .NET Core 2.1.
Cette nouvelle mouture disponible en RC1 depuis le début du mois, apporte son lot de nouvelles fonctionnalités, toute plus attendues les une des autres. En voici la liste :
- Lazy loading
- Data seeding
- Query types
- Value conversions
- Non-default constructors
- GroupBy translation
- Include for derived types
- Change tracking events
- System.Transactions support
- Column ordering
- [Owned] attribute
- Correlated subquery optimization
- Cosmos DB provider preview
- Oracle provider sample
- UWP testing & improvements
Nous allons revenir sur les exemples présentés durant la session.
Data seeding
Le data seeding permet de pré-remplir la base de données avec des données que vous jugez nécessaires au bon fonctionnement de votre application. Si je reprends l'exemple de la session, ils créent une application de gestion de blog, avec des articles et des thèmes, ils souhaitent pré-remplir les thèmes et cela se fait à travers la méthode "HasData" qui prend soit des objets typés, soit des objets dynamiques (à utiliser quand il y a des relations, ici Blog/Theme).
modelBuilder.Entity<Theme>().HasData(new Theme {ThemeId = 1, Name = "Build2018"}); modelBuilder.Entity<Blog>().HasData( new {BlogId = 1, Theme1 = 1, Title = "//MS BUILD 2018 – ANNONCES ET NOUVEAUTÉS SERVERLESS DANS AZURE", Link = "https://blogs.infinitesquare.com/posts/build2018/ms-build-2018-annonces-et-nouveautes-serverless-dans-azure"}, new {BlogId = 2, Theme1 = 1, Title = "Les dernières annonces sur le développement SharePoint", Link = "https://blogs.infinitesquare.com/posts/build2018/les-dernieres-annonces-sur-le-developpement-sharepoint"});
Il est également conseillé d'utiliser les outils de migration proposés par EF pour générer automatiquement les fichiers de migration de données, il est également possible de générer du SQL brut. Pour plus d'info sur la migration, vous pouvez consulter la documentation Migrations - EF Core.
Value conversions
Les value conversions vous permettent d'utiliser des types sur propriété de classe, non gérés par les bases de données qui transforment le type par un type géré par votre base de données. Vous pouvez ainsi manipuler des types dans vos classes et ce de manière transparente, sans avoir à utiliser des helpers pour convertir la donnée en entrée et en sortie, EF le fait automatiquement pour vous, un fois le converter défini.
Dans EF, des converters sont déjà disponibles (la liste complète), mais vous pouvez également écrire votre propre converter. Si nous reprenons l'exemple de la Build, à savoir pouvoir utiliser le type Sytem.Drawing.Color sur la classe précédente, "Theme", le code nécessaire pour le converter est le suivant :
modelBuilder .Entity<Theme>() .Property(e => e.TitleColor) .HasConversion( v => v.Name, v => Color.FromName(s));
La méthode HasConversion prend en paramètre, 2 lambdas, la première étant en entrée de la base de données (ajout de la donnée), la seconde étant en sortie de la base de données (lecture de la donnée).
Lazy loading
Le lazy loading permet de charger dynamiquement des données liées. Comparé au "Eager loading" (chargement des données liées de manière explicites), ce fonctionnement étant assez dangereux, est à utiliser en étant très précautionneux, il peut facilement partir en boucle sans fin s'il n'est pas maîtrisé. Pour activer le lazy loading, il faut utiliser la méthode UseLazyLoadingProxies, comme ceci :
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .UseLazyLoadingProxies(); }
Il est nécessaire de marquer comme virtual les propriétés de navigation (comme pour EF6).
public class Blog { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<Post> Posts { get; set; } } public class Post { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public virtual Blog Blog { get; set; } }
Il est également possible d'utiliser le lazy loading sans la génération de classes proxy (dans certains cas, il n'est pas autorisé de créer des classes dynamiquement), exemple disponible ici.
Query types
Les query types permettent d’interroger des données n'étant pas mappées à des entités (avec un identifiant unique). Typiquement, cela va être utile pour être mappé a :
- Des vues
- Des tables qui n'ont pas de clé primaire
- Des procédures stockées
Si nous prenons l'exemple d'une vue de la forme suivante :
CREATE VIEW BlogPostCounts AS SELECT Name, Count(p.PostId) as PostCount from Blogs b JOIN Posts p on p.BlogId = b.BlogId GROUP BY b.Name
Il suffit de créer une classe avec les propriétés Name et PostCount
public class BlogPostsCount { public string BlogName { get; set; } public int PostCount { get; set; } }
Et d'ajouter dans le contexte, un DbQuery, semblable à un DbSet mais qui ne permet pas de faire des actions d'ajout/modification/suppression.
public DbQuery<BlogPostsCount> BlogPostCounts
EF Core 2.2, 3.0 !
La version 2.1 venant juste de sortir, les équipes ne s'arrêtent pas là, elles prévoient déjà la version 2.2, et même la 3.0 !
Pour la version 2.2, les fonctionnalités Cosmos DB provider (pour faire suite à la version preview de 2.1) et Collections of owned types, sont déjà actées. Les autres sont encore en discussion, et seront ajoutées en fonction des retours en interne, ainsi que de la communauté (pour voter, c'est par ici). Pour ma part, j'attend avec impatience, le mapping des colonnes JSON, les relations "Many-to-Many", le mapping des procédures stockées.
Commentaires