2010-09-13 5 views
1

J'ai un IEnumerable de factures, ces factures ont des éléments de campagne. Ces éléments de campagne ont la priorité. Je programme une variété de stratégies pour appliquer automatiquement de l'argent sur ces éléments de campagne et l'un d'eux me cause des problèmes. Mon modèle a consisté à préparer une instruction linq pour ordonner les éléments de ligne des factures, puis itérer sur la requête linq en appliquant de l'argent dans l'ordre jusqu'à ce que je sois épuisé.Tough Linq Query

Un exemple de cette déclaration LINQ pour la stratégie la plus simple, payer chaque ligne par priorité et la date d'échéance, est indiqué ci-dessous:

from lineItem in invoices.SelectMany(invoice => invoice.LineItems) 
orderby lineItem.Priority, lineItem.DueDate 
select lineItem; 

L'une des stratégies consiste à appliquer l'argent à l'élément restant le plus ancien avec une priorité donnée, dans l'ordre de priorité, puis passer à la plus ancienne suivante de chaque priorité.

EDIT: Exemple de la façon dont on pourrait commencer à la requête que je demande -

from lineItem in invoices.SelectMany(invoice => invoice.LineItems) 
group lineItem by lineItem.Priority into priorities 
orderby priorities.Key 
select priorities.OrderBy(item => item.DueDate); 

Nous avons maintenant « seaux » d'articles en ligne avec la même priorité, commandés par date d'échéance dans le seau. J'ai besoin d'extraire le premier élément de chaque seau, suivi par le second, etc. jusqu'à ce que j'ai commandé tous les articles. Je voudrais effectuer cette commande purement en linq.

Quelqu'un peut-il penser à un moyen d'exprimer cela entièrement dans linq?

+0

Vous venez de le faire! Que demandez-vous que votre requête ne fait pas déjà? – Timwi

+1

@Timwi - Je pense que l'exemple montre une stratégie simplifiée - la stratégie réelle requise est résumée dans un seul paragraphe sous le code. @ marr75 il serait vraiment utile si vous pouviez nous donner un exemple concret - comme par exemple 'LineItems' et l'ordre dans lequel ils devraient être achetés en utilisant la nouvelle stratégie. –

+2

La première requête fait exactement ce que les états de paragraphe est requis. La deuxième requête (après le "Edit") fait un certain groupement fantaisie qui ne semble pas nécessaire. – Timwi

Répondre

4

Je ne vois pas comment vous obtenez cela à une meilleure requête que ce que vous avez, peut-être le nid from requêtes pour faire automatiquement le SelectMany.

var proposedPayments = new List<LineItem>(); 
decimal cashOnHand = ...; 
var query = invoices.SelectMany(iv => iv.LineItems) 
        .GroupBy(li => li.Priority) 
        .SelectMany(gg => 
         gg.OrderBy(li => li.DueDate) 
          .Select((li,idx) => Tuple.Create(idx, gg.Key, li))) 
        .OrderBy(tt => tt.Item1) 
        .ThenBy(tt => tt.Item2) 
        .Select(tt => tt.Item3); 
foreach (var item in query) 
{ 
    if (cashOnHand >= item.Cost) 
    { 
     proposedPayments.Add(item); 
     cashOnHand -= item.Cost; 
    } 

    if (cashOnHand == 0m) break; 
} 

Edit: mis à jour pour correspondre au paragraphe l'auteur a voulu. Sélectionné en tant que premier de chaque priorité.

+0

D'accord, l'exemple de requête que j'ai donné était bien, je n'ai peut-être pas été clair, j'ai besoin d'une requête pour exprimer l'ordre dont je parlais dans le paragraphe après. – marr75

+0

@ marr75: fait pour correspondre à ce que vous cherchiez. – user7116

+0

Oui, c'est sur ce que j'ai fini avec. Je n'ai pas utilisé un tuple, mais plutôt un type anonyme (appeler une propriété Rank ajoute de la lisibilité). Merci StackOverflow de rester avec moi à ce sujet. – marr75

0

LINQ = Langue intégrée QUERY pas de langue CODE PROCEDURAL intégré.

Si vous souhaitez obtenir une requête renvoyant les éléments de campagne auxquels vous souhaitez appliquer le paiement, vous pouvez effectuer cette opération (voir .Aggregate), mais si vous souhaitez réellement appliquer l'argent aux éléments de campagne au fur et à mesure, une boucle foreach est une belle construction à utiliser.

Voir http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

+0

Oui, je sais, je vais bien appliquer une boucle foreach après avoir commandé les éléments de campagne, de cette façon les effets secondaires sont explicites. Ce que je cherche, c'est un moyen d'exprimer l'ordre de la deuxième stratégie dont j'ai parlé. – marr75

+1

@ marr75: Quelle est la différence entre la "deuxième stratégie" et celle que vous avez déjà codée? Il me semble que votre requête existante devrait fonctionner ... –

+0

C'est une différence subtile, laissez-moi savoir si l'exemple ajouté permet de faire la distinction claire. – marr75