2009-07-22 6 views
0

Je suis assez nouveau à linq et luttant pour créer une requête. J'ai une table 'Customers' et une table 'Orders', relation one-to-many. Comment sélectionner les clients ayant la commande la plus ancienne avec le mot "spécial" dans la description de la commande?Linq question de question (un à plusieurs, filtre de propriété d'objet enfant)

Si la commande la plus ancienne ne contient pas ce mot, le client ne devrait pas figurer dans le résultat. Si le client n'a pas d'ordres, il ne devrait pas être dans le résultat. En d'autres termes, seuls les clients qui ont des commandes et dont l'ordre le plus ancien a le mot «spécial» devraient s'y trouver.

J'espère que je suis clair et merci.

Répondre

3

Liste public static < Client > SampleSelect (Liste < clients client >)
{
        retour clients.Where (c = 0 > c.Orders.Count > & &
                                                                          c.Orders.OrderBy (o = > o.Date)
                                                                                          .FirstOrDefault(). Description.Conta ins ("Spécial")). ToList();
}

// commande fixe, thnx à Ryan Versaw

+0

Cela devrait être ordre croissant plutôt que décroissant. –

+0

Oui, mais c'est mineur, l'algorithme est correct, ce qui est plus important. – Valentin

+0

Ouais, je sais que c'était mineure - C'est pourquoi j'ai commenté et voté vers le haut :) –

1

Ceci est une estimation rapide extrapolant ce que je peux de votre question. Il peut ou non être précis:

var dc = new MyDataContext();  
var qry = from customer in dc.Customers 
      where customer.Orders.Description.Contains("special") 
      && customer.Orders.OrderDate > myMinDate 
      && customer.Orders.OrderDate < myMaxDate 
      order by customer.Orders.OrderDate ascending 
      select customer; 

Il doit retourner des objets clients commandés par leurs dates de commande, filtrés par une min et la date max. Ces deux lignes peuvent être supprimées si vous ne souhaitez pas filtrer par date.

Attendez que les clients à répéter. Si vous n'avez pas besoin de répéter, ajoutez une clause group by.

Bonne chance avec, rapportez comment ça marche. :)

Edit:

Merci, Randolpho, le problème est que je n'ai pas myMinDate et myMaxDate. Je dois pouvoir inspecter la description de l'ordre le plus ancien. Je pense que je devrais utiliser quelque chose comme où c.Orders.Where (x => x.OrderDate.Max()), mais ne peut pas composer toute la requête correctement. Merci. - Valentin Vasiliev

Hmm ... Je ne peux pas dire si vous voulez que le client le plus ancien ordre et de celui que vous souhaitez inspecter la description ou si vous voulez que le client le plus ancien ordre que a le mot "spécial" dans la description de l'ordre.

Si vous voulez que le client le plus ancien ordre et que vous souhaitez ensuite vérifier la description, vous devez faire quelque chose comme ceci:

var qry = from customer in dc.Customers 
      order by customer.Orders.OrderDate ascending 
      select new 
      { 
      CustomerData = customer, 
      OrderDescription = customer.Orders.Description 
      }; 
var oldest = qry.First(); 
if(oldest.OrderDescription.Contains("special")) 
{ 
    // do something 
} 

Dans ce scénario, le plus ancien est un nouveau type anonyme qui a deux champs, CustomerData, qui contient le client avec la commande la plus ancienne, et OrderDescription, qui contient le champ de description de la commande la plus ancienne. D'autre part, vous voudrez peut-être l'ordre le plus ancien qui contient le mot "spécial". Dans ce cas, vous devez faire quelque chose comme ceci:

var qry = from customer in dc.Customers 
      where customer.Orders.Description.Contains("special") 
      order by customer.Orders.OrderDate ascending 
      select customer; 
var oldestCustomerWithSpecial = qry.First(); 

Dans ce scénario, le client le plus ancien qui contient le mot dans la description « spéciale » est dans la variable nommée oldestCustomerWithSpecial.

Je ne pense pas que l'utilisation de Max sur OrderDate vous aidera. Vous êtes presque toujours mieux d'utiliser une commande par date TOP 1 requête. Appeler First() sur la requête fera cela.

+0

Merci, Randolpho, le problème est que je n'ai pas myMinDate et myMaxDate. Je dois pouvoir inspecter la description de l'ordre le plus ancien. Je pense que je devrais utiliser quelque chose comme où c.Orders.Where (x => x.OrderDate.Max()), mais ne peut pas composer toute la requête correctement. Merci. – Valentin

+0

Mon cas est le premier. Malheureusement, il ne compile pas, je ne peux pas accéder à OrderDate ici: ordre par customer.Orders.OrderDate croissant, puisque Orders est une collection. – Valentin