Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Abonnements

Pourquoi utiliser Entity Framework ?

Certains l’auront remarqué, j’ai encore pris un an de plus. Et j’ai décidé qu’il était temps pour moi d’écouter un peu les vieux :p (je pense particulièrement à Mitsu et Redo en l’occurrence que je remercie par la même occasion pour me faire profiter de leur expérience)

A travers cet article, je vais tenter de rester à un niveau 100/200 (ce qui constitue un vrai challenge pour moi que m’a fixé Redo ;)) afin de vous convaincre des bienfaits de l’Entity Framework.

Pour cela, nous allons partir d’un exemple simple et nous allons étudier l’implémentation avec les DataReaders, LINQ To SQL et Entity Framework.

Dans notre exemple, la base est la suivante :

image

La méthode que je veux implémenter doit retourner les 10 meilleurs membres  (par rapport au total qu’ils ont dépensés) avec leurs propriétés Points, CompanyName, ContactName et le montant qu’ils ont dépensé.

Pour cela, nous utiliserons une classe MemberInfo :

public class MemberInfo
{
   
public string CustomerId { get; set
; }
   
public string CompanyName { get; set
; }
   
public string ContactName { get; set
; }
   
public int Points { get; set
; }
   
public double Amount { get; set; }
}
 

DataReader


Commençons avec l’implémentation utilisant les DataReaders.

public static List<MemberInfo> GetMembers()
{
    List<MemberInfo> value = new List<MemberInfo>();
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString))
    {
        connection.Open();
        using (SqlCommand command = new SqlCommand("SELECT TOP 10 MI.CustomerID, MI.CompanyName, MI.ContactName, MI.Points, COALESCE(MI.Amount,0) AS Amount FROM ( " +
            "SELECT C.CustomerID, C.CompanyName, C.ContactName, M.Points, ( SELECT SUM(OD.UnitPrice * OD.Quantity * (1 - OD.Discount)) FROM Orders O " +
            "INNER JOIN OrderDetails OD ON OD.OrderID = O.OrderID WHERE O.CustomerID = C.CustomerID) AS Amount FROM Customers C " +
            "INNER JOIN Members M on M.CustomerID = C.CustomerID ) MI ORDER BY MI.Amount DESC", connection))
        {
            using (SqlDataReader dataReader = command.ExecuteReader())
            {
                while (dataReader.Read())
                    value.Add(new MemberInfo { CustomerId = dataReader.GetString(0), CompanyName = dataReader.GetString(1),
                        ContactName = dataReader.IsDBNull(2) ? null : dataReader.GetString(2), Points = dataReader.GetInt32(3), Amount = dataReader.GetDouble(4) });
            }
        }
    } return value;
}

 

Ce code est un peu pénible à écrire à cause de la gestion de la Connection, de la Command et du DataReader.  

De plus, le fait de passer la requête en chaîne de caractères n’est évidemment pas l’idéal : difficile à relire, avec potentiellement des fautes de frappe qui ne seront visibles qu’à l’exécution sous la forme d’une exception.

Enfin, notre code est lié à SQL Server.

LINQ To SQL


Implémentons maintenant ce même exemple avec LINQ To SQL.

image

Avec LINQ To SQL, le code est le suivant :

public static List<MemberInfo> GetMembers()
{
    
using (NorthwindDataContext context = new NorthwindDataContext
())
     {
        
return (from m in
context.Members
                
let
c = m.Customer
                
let amount = (double?)c.Orders.SelectMany(o => o.OrderDetails).Sum(od => (double)od.Quantity * (double
)od.UnitPrice * (1 - od.Discount))
                
orderby amount descending                  select new MemberInfo { CustomerId = c.CustomerID, CompanyName = c.CompanyName, ContactName = c.ContactName, Points = m.Points, Amount = amount ??
0 }).Take(10)
                .ToList();
     }
}
 

Reprenons les points évoqués précédemment :

Ce code est beaucoup moins peu pénible à écrire : pas besoin de gérer la Connection, la Command et le DataReader.

De plus, en utilisant une requête LINQ (LINQ To SQL ici), nous bénéficions de l’intellisense et des navigation properties ce qui augmente notre productivité. Nous n’avons pas besoin de connaître et C# (ou VB .NET) et T-SQL, C# ou VB.Net étant suffisants. De plus, la coloration syntaxique augmente la lisibilité de la requête. Enfin, la requête est compilée ce qui veut dire qu’on élimine les risques de faute de frappe visible qu’à l’exécution. Si on fait une faute de frappe, notre code ne compilera simplement pas.

En revanche, notre code reste lié à SQL Server.

Entity Framework


Contrairement à LINQ To SQL, Entity Framework possède un vrai modèle de mapping permettant d’envisager une conception des entités différentes de la conception de la base. Cela est très important. En effet, les entités étant conçues (dans le cas de C# ou VB.NET par exemple) avec une conception orientée objet alors que la base sera conçue avec une conception relationnelle. Entre ces deux conceptions les contraintes ne sont pas les mêmes (l’exemple le plus simple qui me vienne à l’esprit est le cas des relations many to many qui n’existent pas dans une conception relationnelle obligeant le passage par une 3ème table). De ce fait, les conceptions optimales des entités et de la base peuvent ainsi être relativement différente qui impose parfois un mapping complexe entre les deux. Une des grandes forces d’Entity Framework repose dans le fait que toute la complexité de ce mapping est gérée par le Framework.

Dans le cas de notre exemple, nous ne travaillons que sur les Members il n’est donc pas judicieux de gérer à la fois une entité Member et une entité Customer.

Aussi dans notre cas, nous allons définir l’Entity Data Model suivant :

image

Cela va ainsi nous permettre de profiter des propriétés CustomerID, CompanyName, ContactName et Points directement sur la même entité : Member.

Cela va donc également simplifier la requête LINQ (LINQ To Entities pour Entity Framework) :

public static List<MemberInfo> GetMembers()
{
    
using (NorthwindEntities context = new NorthwindEntities
())
     {
        
return (from m in
context.Members
                
let amount = (double?)m.Orders.SelectMany(o => o.OrderDetails).Sum(od => (double)od.Quantity * (double
)od.UnitPrice * (1 - od.Discount))
                
orderby amount descending
                 select new MemberInfo { CustomerId = m.CustomerID, CompanyName = m.CompanyName, ContactName = m.ContactName, Points = m.Points, Amount = amount ??
0 }).Take(10)
                .ToList();
     }
}
 

Entity Framework n’étant pas limité à SQL Server, nous avons ainsi pu résoudre l’ensemble des problématiques que nous avions évoquées avec la première implémentation (en utilisant les DataReaders)

Conlusion


LINQ nous a permis de :

·         Gagner en productivité et en lisibilité

·         Nous abstraire du SQL  en exécutant nos requêtes directement sur nos entités


Entity Framework nous a permis de :

·         Nous abstraire du provider de base de données. Dans notre cas, il est par exemple possible de passer d’une Oracle à une base SQL Server sans toucher une seule ligne de code !

·         Nous abstraire de la base lors de la conception des entités de façon  à nous permettre de concevoir celles-ci en fonction de leur utilisation et non en fonction des contraintes liées au modèle de persistance.


S’il fallait encore vous convaincre, je rajouterai le fait qu’Entity Framework s’inscrit vraiment, de mon point de vue, comme LA techno d’accès aux données dans la stratégie de Microsoft. Il suffit d’utiliser WCF RIA Services ou WCF Data Services pour s’en convaincre. Ces technos peuvent être utilisées sans Entity Framework mais la productivité est telle quand on les associe à Entity Framework qu’il serait dommage de s’en passer.

 

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Publié jeudi 25 novembre 2010 00:59 par Matthieu MEZIL

Commentaires

# re: Pourquoi utiliser Entity Framework ? @ jeudi 25 novembre 2010 08:23

Le challenge est réussit haut la main :)

fabrice.michellonet

# re: Pourquoi utiliser Entity Framework ? @ jeudi 25 novembre 2010 08:34

:)

Matthieu MEZIL

# re: Pourquoi utiliser Entity Framework ? @ jeudi 25 novembre 2010 10:27

Vraiment du bon boulot, et très bien expliqué. Je t'avoue que je n'avais jamais regardé tout ça en profondeur, sans même connaitre les avantages à utiliser EF, je suis convaincu maintenant :-).

Danuz

# re: Pourquoi utiliser Entity Framework ? @ jeudi 25 novembre 2010 10:55

Et au niveau des performances ?

Il y avait des tests réalisés à ce sujet avec l'ancienne version de EF et aussi NHibernate.

Rien de tel qu'un bon DataReader et des procédures stockées pour avoir un gain de performance par rapport aux autres méthodes.

Je n'ai pas fait le test avec la dernière version de EF 4.

MisterG

# re: Pourquoi utiliser Entity Framework ? @ jeudi 25 novembre 2010 12:47

@Matthieu : Félicitations, trés bon article

@MisterG : Au niveau des performances, c'est comme tout : Tu peux faire des requêtes Linq To Entities "moisies" qui vont mettre ton serveur de données en croix.

La performance, c'est aussi une question de connaissances du produit que tu utilises (que ce soit EF ou du pur SQL)

Un bon exemple : Un post sur les perfs EF que j'ai fais y'a pas longtemps :

http://www.dotmim.com/2010/10/19/performances-entity-framework-4-pagination/

Pour info, on parle de Millions de lignes là

Mimetis

# re: Pourquoi utiliser Entity Framework ? @ jeudi 25 novembre 2010 18:38

@David : très content de pouvoir me rendre utile. Pour ma part, je suis convaincu que Redo et Mitsu avaient raison (comme d'hab ;))

@MisterG : les plans d'exécution des 3 versions sont les mêmes

@ Mimetis : Les perfs avec EF4 sont excellentes... à condition de comprendre ce que l'on fait quand on écrit une requête L2E. J'interviens souvent sur des audits à cause des perfs liées aux requêtes L2E. A ce jour, je n'ai jamais vu de mauvaises perfs après mon passage. En revanche, j'ai déjà eu des ratios parfois de plus de 100 entre la requête avant et après mon passage...

J'ai écrit un article sur l'optimization de requêtes LINQ To Entities que je viens de soumettre à Corp pour publication sur msdn us. J'espère qu'il sera bientôt en ligne. Je vous tiendrai au courant.

Matthieu MEZIL

# re: Pourquoi utiliser Entity Framework ? @ jeudi 25 novembre 2010 22:17

Bonjour, on à eu une présentation aujourd'hui sur Entity Framework et je pense aussi que c'est une superbe solution.

Mais malheureusement pour nous, nos clients sont sur Oracle et nous ne pouvons attendre un hypothétique provider de Oracle.

Je trouve cela dommage et nous ne voulons pas passer par des tiers Comme devArt ou autres.

Mais quand tu dis que Entity Framework nous à permis de passer d'une base Oracle à une Base Sql, c'est pas vrai pour le moment sans passer par des tiers avec des royalties assez élevés?

Pascalsa

# re: Pourquoi utiliser Entity Framework ? @ vendredi 26 novembre 2010 09:55

Bravo Matthieu, j'aime quand tes articles sont accessibles ;)

Graveen

# re: Pourquoi utiliser Entity Framework ? @ vendredi 26 novembre 2010 23:29

Soudain... le miracle s'accomplit... Matthieu écrivit en niveau 200 ! ALLELUIA !!! ;)

vLabz

# re: Pourquoi utiliser Entity Framework ? @ samedi 27 novembre 2010 00:54

@Pascalsa:

Je peux me tromper mais je ne crois pas qu'il y ait de royalties avec DevArt ou DataDirect, juste des licenses dévelopeurs à acheter. Alors c'est vrai, ce n'est pas gratuit (tant qu'Oracle n'a pas encore sorti son provider) mais ça a le mérite d'exister. A noter que pour DB2, MySQL, etc, je crois qu'il y a des providers gratuits.

@ Graveen &amp; Vincent : :)

Matthieu MEZIL

# re: Pourquoi utiliser Entity Framework ? @ samedi 27 novembre 2010 09:01

Ok merci je vais regarder cela de plus près. Mais il y a quelque chose qui m'échappe, pourquoi Oracle traîne comme cela. Car pour nos nouveaux produits on pensent fortement à passer sur SQL. En tous cas merci pour la réponse.

Pascalsa

# re: Pourquoi utiliser Entity Framework ? @ samedi 27 novembre 2010 09:50

La stratégie d'Oracle est parfois étonnante vis à vis de MS. A mon avis leur idée première était de pénaliser MS en ne proposant pas de provider et également d'attendre pour voir si EF allait prendre chez les devs.

Maintenant ils se rendent probablement compte que ne pas avoir de provider gratuit développer par eux-mêmes les dessert plus que ne dessert MS. Du coup ils s'y mettent. Mais devant la qualité du SQL généré par le provider pour SQL Server, ils ont du boulot pour être à la hauteur plus le fait que je ne pense pas qu'ils investissent énormément sur ce dev, ça explique pourquoi ils ont besoin d'un an pour développer leur provider.

Matthieu MEZIL

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01