Reputation: 19307
There are classes Client and Commande :
public class Client {
public int Identifiant { get; set; }
public string Nom { get; set; }
public int Age { get; set; }
}
public class Commande
{
public int Identifiant {get; set;}
public int IdentifiantClient {get;set;}
public decimal Prix {get;set;}
}
Here are some lists based on these classes :
List<Client> listeClients = new List<Client>
{ new Client{Identifiant=1,Nom="Nicolas",Age=30},
new Client{ Identifiant = 2, Nom = "Jérémie", Age = 20},
new Client{ Identifiant=3, Nom="Delphine", Age=30},
new Client{Identifiant = 4, Nom = "Bob", Age = 10}
};
List<Commande> listeCommandes = new List <Commande>
{
new Commande{Identifiant=1, IdentifiantClient=1, Prix = 150.05M},
new Commande{Identifiant=2, IdentifiantClient= 2, Prix= 30M},
new Commande{Identifiant= 3, IdentifiantClient= 1, Prix= 99.99M},
new Commande{Identifiant= 4, IdentifiantClient= 1, Prix= 100M},
new Commande{Identifiant= 5, IdentifiantClient = 3, Prix = 80M},
new Commande{Identifiant = 6, IdentifiantClient = 3,Prix = 10M}
};
Now there is this Linq expression :
var liste = from commande in listeCommandes
join
client in listeClients on commande.IdentifiantClient equals client.Identifiant
group commande by new {commande.IdentifiantClient, client.Nom}
into commandesGroupees
let total = commandesGroupees.Sum(c => c.Prix)
where total > 50
orderby total
select new {
commandesGroupees.Key.IdentifiantClient,
commandesGroupees.Key.Nom,
NombreDeCommandes = commandesGroupees.Count(),
PrixTotal = total
};
foreach(var element in liste)
{
Console.WriteLine("Le client {0} ({1}) a réalisé {2} commande(s) pour un total de {3}", element.Nom, element.IdentifiantClient, element.NombreDeCommandes, element.PrixTotal);
}
In the Linq expression there is this expression : let total = commandesGroupees.Sum(c => c.Prix)
. How is it possible that the parameter c represents an instanciation of the Command class ? because there is the calling of the property Prix
!
Upvotes: 1
Views: 79
Reputation: 271595
Let's analyse this query expression bit by bit.
from commande in listeCommandes
It is clear that if listeCommandes
is a List<Commande>
, commande
should be of type Commande
. Right?
join
client in listeClients on commande.IdentifiantClient equals client.Identifiant
This join joins the client list to the query. Now we have a client
variable of type Client
. But this doesn't have much to do with commande
, which is still of type Commande
.
group commande by new {commande.IdentifiantClient, client.Nom}
into commandesGroupees
This is where it gets interesting. When you group commande
, a bunch of IGrouping<AnonymousClass, Commande>
are created. This is exactly the commandesGroupees
here.
So what happens if you call Sum
on a IGrouping<AnonymousClass, Commande>
? Remember that Sum
is an extension method on IEnumerable<T>
, and IGrouping<AnonymousClass, Commande>
implements IEnumerable<Commandes>
. This means that you are basically calling Sum
on a IEnumerable<Commandes>
, which expects a Function<Commande, decimal>
.
Upvotes: 2
Reputation: 3603
Let's chunk it in smaller bits to make it simpler
from commande in listeCommandes
commande is of type Commande
group commande by new { commande.IdentifiantClient, client.Nom }
This is probably the bit confusing you, this still creates an IEnumerable<Commande> not an IEnumerable<anonymous<identifiantclient,nom>>, the new is what you want to group by, not what you want the grouped items to be, at this point you're creating an IGrouping that has IdentifiantClient and Nom as key but has an IEnumerable has an element
into commandesGroupees
Gives a name to the IGrouping we previously created
let total = commandesGroupees.Sum(c => c.Prix)
An IGrouping<TKey,TValue> is an IEnumerable<TValue> so as we've seen earlier each of the groups (grouped by idenfiantClient and Nom) hold a sequence of commands, since we're doing a linq query on it (sum) we're not concerned about the key but about the IEnumerable that is exposed (the IEnumerable<Command>).
This is why the sum works on Command and those have a Prix property.
Upvotes: 2