Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Abonnements

LINQ To Entities

Cette semaine je suis à Montréal en tant que speaker sur Entity Framework pour l’évènement confoo. J’en profite pour remercier les organisateurs de cet évènement de m’avoir fait confiance et Access-IT de m’avoir permis d’y participer.

En parallèle, j’ai profité de ma venu pour enregistrer un podcast Visual Studio Talk Show, avec Guy Barette et Mario Cardinal les célèbres animateurs de cette émission culte, qui devrait bientôt être en ligne et j’ai également animé une journée d’ateliers Entity Framework pour la communauté .NET de Montréal.

J’en profite pour remercier Guy de m’avoir donné cette occasion.

Cette journée d’ateliers c’est décomposée en 3 parties :

  • Le mapping
  • Le requêtage
  • Les template T4

Comme promis, je vous met à disposition le pps et surtout la correction des requêtes L2E.

Enjoy Smile

 

clip_image002

 


·        Parcourez l’ensemble des clients et affichez leur type dans la console

using (var context = new MyNorthwindEFEntities())
{
    foreach (var c in context.Customers)
        Console.WriteLine(c.GetType());
}

Parmi les DAL.Customer, vous devriez voir quelques DAL.Member.

 

·        Récupérez le nom des clients ayant une carte de membre

from c in context.Customers.OfType<Member>()
select c.ContactName;

 

·        Récupérez les sociétés des clients habitant Montréal, Québec, Canada

string city = "Montréal";
string region = "Québec";
string country = "Canada";


from c in context.Customers
where c.Address.City == city && c.Address.Region == region && c.Address.Country == country
select c.CompanyName;

 

·        Récupérez les clients triés par nom

from c in context.Customers
orderby c.ContactName
select c;

 

·        Récupérez le nom et la société des clients habitant Montréal

string city = "Montréal";

 

from c in context.Customers
where c.Address.City == city
select new { c.CompanyName, c.ContactName };

 

·        Récupérez les catégories avec leur nombre de produits triées par leur nombre de produits (décroissant)

from c in context.Categories
let nbProducts = c.Products.Count
orderby nbProducts descending
select new { Category = c, NbProducts = nbProducts };

 

·        Récupérer les vendeurs avec leur CA généré triés par CA (décroissant)

from e in context.Employees
let sold = e.Orders.Sum(o => o.OrderDetails.Sum(od => (double)od.Quantity * (double)od.UnitPrice * (1D - od.Discount)))
orderby sold descending
select new { Employee = e, Sold = sold };

 

·        Récupérez du 21ème au 30ème meilleurs clients (inutile de récupérer le montant dépensé)

int skip = 20;
int take = 10;

 

(from c in context.Customers
 orderby c.Orders.Sum(o => o.OrderDetails.Sum(od => (double)od.Quantity * (double)od.UnitPrice * (1D - od.Discount))) descending
 select c).Skip(skip).Take(take);

 

·        Récupérez le meilleur vendeur par catégorie avec le CA

from c in context.Categories
let bestEmployee = 
    (from e in context.Employees
     let sold = e.Orders.Sum(o => o.OrderDetails.Where(od => od.Product.CategoryID == c.CategoryID).Sum(od => (double)od.Quantity * (double)od.UnitPrice * (1D - od.Discount)))
     where sold != null
     orderby sold descending
     select new { Employee = e, Sold = sold }).FirstOrDefault() 
where bestEmployee.Sold != null
select
new { Category = c, BestEmployee = bestEmployee.Employee, Sold = bestEmployee.Sold };

 

·        Récupérez les 10 meilleures dates de vente avec le montant des ventes

int take = 10;

 

var q = from o in context.Orders
             select new { o.OrderDate, Amount = o.OrderDetails.Sum(od => (double)od.UnitPrice * od.Quantity * (1D - od.Discount)) };

var q2 = (from o in q
                group o by o.OrderDate into g
                let sold = g.Sum(o => o.Amount)
                orderby sold descending
                select new { Date = g.Key, Sold = sold }).Take(take);

 

·        Récupérez les 3 meilleures années de vente

int take = 3;

 

var q = from o in context.Orders
             select new { o.OrderDate, Amount = o.OrderDetails.Sum(od => (double)od.UnitPrice * od.Quantity * (1D - od.Discount)) };

var q2 = (from o in q
                group o by o.OrderDate.Value.Year into g
                let sold = g.Sum(o => o.Amount)
                orderby sold descending
                select new { Year = g.Key, Sold = sold }).Take(take);

 

·        Récupérez la ou les (en cas d’égalité) meilleure(s) catégorie(s) de chaque vendeur

from e in context.Employees
let categories =
    from c in context.Categories
    let sold = c.Products.Sum(p => p.OrderDetails.Where(od => od.Order.EmployeeID == e.EmployeeID).Sum(od => (double)od.Quantity * (double)od.UnitPrice * (1D - od.Discount)))
    where sold != null
    select new { Category = c, Sold = sold }
let maxSold = categories.Select(c => c.Sold).Max()
select new { Employee = e, BestCategories = categories.Where(c => c.Sold == maxSold).Select(c => c.Category) };

 

·        Récupérez la liste des employés encore en activé avec leur ancienneté (par rapport à la date de la base de données) triés par ancienneté

Ouvrez l’edmx en mode xml (click droit, open with, Xml (Text) Editor).

Allez dans la partie CSDL puis dans l’élémént Schema.

Ajoutez-y le code suivant :

<Function Name="DiffYearsToCurrent" ReturnType="Int32">
  <Parameter Name="date" Type="DateTime" />
  <DefiningExpression>
    DiffYears(date, CurrentDateTime())
  </DefiningExpression>
</Function>

Ensuite ajoutez une nouvelle classe DateTimeExtension avec le code suivant :

public static class DateTimeExtension
{
    [EdmFunction("MyNorthwindEFModel", "DiffYearsToCurrent")]
    public static int DiffYearsToCurrent(this DateTime p)
    {
        throw new NotSupportedException();
    }
}

Vous pouvez maintenant utiliser la méthode DiffYearsToCurrent dans vos requêtes LINQ To Entities.

from e in context.Employees.OfType<EmployeeInActivity>()
where e.HireDate != null
let nbYears = e.HireDate.Value.DiffYearsToCurrent()
orderby nbYears descending
select new { Employee = e, HireOld = nbYears };

 

·        Afin de ne pas s’embêter avec le e.HireDate != null et le .Value, rajoutez le directement dans le modèle afin de filtrez tous les employés

Sur le mapping de l’entity type Employee, rajoutez la condition HireDate Is Not Null (avec la fenêtre de mapping) et passez la propriété HireDate à Not Nullable (avec la fenêtre de propriétés)

 

·        Récupérez de nouveau la liste des employés encore en activé avec leur ancienneté (par rapport à la date de la base de données) triés par ancienneté

from e in context.Employees.OfType<EmployeeInActivity>()
let nbYears = e.HireDate.DiffYearsToCurrent()
orderby nbYears descending
select new { Employee = e, HireOld = nbYears };

 

·        Récupérez les employés en activité ayant plus de 10 ans d’ancienneté avec l’ensemble de leurs Orders chargés (en une seule requête SQL)

int nbYears = 10;

 

from e in context.Employees.OfType<EmployeeInActivity>().Include("Orders")
where e.HireDate.DiffYearsToCurrent() >= nbYears
select e;

 

·        Récupérez les employés dont le prénom ne contient que des caractères alphabétique (ie sans accent ni caractère spéciaux)

from e in context.Employees.AsEnumerable()
where Regex.IsMatch(e.FirstName, "^[A-Za-z]*$")
select e;

 

·        Récupérez les employés en activité ayant plus de 10 ans d’ancienneté avec leurs 10 dernières ventes chargées (en une seule requête SQL)

int nbYears = 10;
int take = 10;

 

(from e in context.Employees.OfType<EmployeeInActivity>()
 where e.HireDate.DiffYearsToCurrent() >= nbYears
 select new
 {
     Employee = e,
     TenLastOrders = (from o in e.Orders
                                 orderby o.OrderDate descending
                                 select o).Take(take)
 }).AsEnumerable().Select(e => e.Employee);

 

·        Récupérez les employés en activité ayant plus de 10 ans d’ancienneté avec leurs 10 dernières ventes chargées avec le détail et le client de celles-ci (en une seule requête SQL)

int nbYears = 10;
int take = 10;

 

(from e in context.Employees.OfType<EmployeeInActivity>()
 where e.HireDate.DiffYearsToCurrent() >= nbYears
 select new
 {
     Employee = e,
     TenLastOrders = (from o in e.Orders
                                orderby o.OrderDate descending
                                select new { Order = o, o.OrderDetails, o.Customer }).Take(take)
 }).AsEnumerable().Select(e => e.Employee);

 

·        Récupérez les Orders des employees en activité depuis moins de 3 ans ou plus en activité depuis plus de 3 ans

var q1 = from o in context.Orders
         where o.EmployeeID != null && o.Employee is EmployeeInActivity && (int)(o.Employee.HireDate.DiffDaysFromNow() / 365.25) < 3
         select o;

//Cast in OutEmployee is not supported by L2E with EF4 RC (only cast on primitive type is supported)
//var q2 = from o in context.Orders
//         where o.Employee != null && o.Employee is OutEmployee && (int)(((OutEmployee)o.Employee).OutDate.DiffDaysFromNow() / 365.25) > 3
//         select o;

var q2 = (from e in context.Employees.OfType<OutEmployee>()
          where (int)(e.OutDate.DiffDaysFromNow() / 365.25) > 3 
          select e.Orders).SelectMany(o => o);

var q = q1.Union(q2);

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é dimanche 14 mars 2010 03:51 par Matthieu MEZIL

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- [ SharePoint Summit 2014 ] Tests de montée en charge SharePoint par Le blog de Patrick [MVP SharePoint] le il y a 45 minutes

- [ SharePoint Summit 2014 ] Bâtir un site web public avec Office 365 par Le blog de Patrick [MVP SharePoint] le il y a 3 heures et 0 minutes

- Kinect + Speech Recognition + Eedomus = Dommy par Aurélien GALTIER le il y a 4 heures et 13 minutes

- [ SharePoint Summit 2014 ] Une méthodologie simple pour concevoir vos applications OOTB SharePoint de A à Z par Le blog de Patrick [MVP SharePoint] le il y a 4 heures et 38 minutes

- //Lean/ - Apprendre à faire des Apps Windows universelles par Blog de Jérémy Jeanson le il y a 8 heures et 33 minutes

- Une culture de la donnée pour tous… par Le blog de Patrick [MVP SharePoint] le il y a 10 heures et 30 minutes

- [ SharePoint Summit 2014 ] L’utilisation de SharePoint 2013 pour la mise en place d’un site Internet Grand Public par Le blog de Patrick [MVP SharePoint] le 04-15-2014, 20:51

- [ SharePoint Summit Montréal 2014 ] Mes présentations sont en ligne par Le blog de Patrick [MVP SharePoint] le 04-15-2014, 18:16

- [ SharePoint Summit Montréal 2014 ] L'intelligence d'affaire dans O365 : enfin facile et économique grâce aux dernières évolution de la Power BI par Le blog de Patrick [MVP SharePoint] le 04-15-2014, 17:07

- [ SharePoint Summit Montréal 2014 ] Kit de démarrage rapide pour de la collaboration en mode Intranet avec SharePoint par Le blog de Patrick [MVP SharePoint] le 04-14-2014, 18:40