[英]Linq to objects and lambda expression
有类Client和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;}
}
以下是基于这些类的一些列表:
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}
};
现在有这个Linq表达式:
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);
}
在Linq表达式中有以下表达式: let total = commandesGroupees.Sum(c => c.Prix)
。 参数c如何代表Command类的实例化? 因为有Prix
属性的调用!
让我们将其分块以使其更简单
from commande in listeCommandes
突击队是突击队类型
group commande by new { commande.IdentifiantClient, client.Nom }
这可能会让您感到困惑,这仍然会创建一个IEnumerable <Commande>而不是IEnumerable <anonymous <identifiantclient,nom >>,新的内容是您要分组的对象,而不是您要分组的对象点,您正在创建一个以IdentifiantClient和Nom为键但具有IEnumerable的IGrouping元素
into commandesGroupees
为我们先前创建的IGrouping命名
let total = commandesGroupees.Sum(c => c.Prix)
IGrouping <TKey,TValue>是IEnumerable <TValue>,因此如我们前面所见,每个组(由idenfiantClient和Nom分组)都包含一系列命令,因为我们正在对其执行linq查询(求和)我们不关心密钥,而是关心公开的IEnumerable(IEnumerable <Command>)。
这就是为什么总和适用于Command且具有Prix属性的原因。
让我们逐点分析此查询表达式。
from commande in listeCommandes
显然,如果listeCommandes
是List<Commande>
,则commande
的类型应为Commande
。 对?
join
client in listeClients on commande.IdentifiantClient equals client.Identifiant
此联接将客户端列表联接到查询。 现在,我们有一个client
类型的Client
变量。 但是,这并不有很多工作要做与commande
,它的类型仍然Commande
。
group commande by new {commande.IdentifiantClient, client.Nom}
into commandesGroupees
这就是它变得有趣的地方。 将commande
分组时,将创建一堆IGrouping<AnonymousClass, Commande>
。 这正是这里的commandesGroupees
。
那么,如果在IGrouping<AnonymousClass, Commande>
上调用Sum
会发生什么? 请记住, Sum
是IEnumerable<T>
的扩展方法,而IGrouping<AnonymousClass, Commande>
实现IEnumerable<Commandes>
。 这意味着您基本上是在IEnumerable<Commandes>
上调用Sum
,这需要Function<Commande, decimal>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.