2010-12-14 20 views
2

Ist es möglich, folgende in eine einfacher lesbare linq oder Lambda-Ausdruck zu konvertieren?C# - Lambda vs verschachtelte Schleifen

Im Wesentlichen ist doc.TierID ein Array (int []) der TierIDs, auf denen sich der Client gerade befindet. Außerdem enthält das Dokumentobjekt ein CommitmentProgram-Objekt, das eine Liste von PriceProgram enthält. Alles, was ich versuche, ist die PriceProgram.ProgramID für jede TierID.

Die Beziehung zwischen PriceProgram und TierID besteht darin, dass jedes PriceProgram eine Liste von Tiers (ProgramTier-Objekt) hat und ProgramTier-Objekt die entsprechende TierID enthält, die wir bereits haben.

Lassen Sie mich wissen, wenn meine Erklärung keinen Sinn ergibt, und ich werde versuchen, es auszuarbeiten.

bearbeiten

Jon, Ich erhalte Der Name 'priceProgram' existiert nicht im aktuellen Kontext Fehler, wenn ich versuche zu kompilieren, was Sie vorgeschlagen haben:

Dictionary<int, int> selectedProgramTierCombo = 
    (from mainTierID in doc.TierID 
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    **join progTier in priceProgram.Tiers on mainTierID equals progTier.TierID** 
    select new { priceProgram.ProgramID, progTier.TierID }) 
    .ToDictionary(x => x.ProgramID, x => x.TierID); 
+0

Mit dem generischen Typ 'System.Collections.Generic.List ' Argument '1' Typ erfordert. – ja72

+0

Ich habe einen aktualisierten Code basierend auf Jons erster Antwort bereitgestellt. –

+0

Ich habe meine Antwort geändert, um eine andere 'from'-Klausel anstelle der' join' zu verwenden ... obwohl es sich anhört, als ob du dieses Bit überhaupt nicht brauchst. –

Antwort

4

Absolut es ist sehr einfach - aber ich muss den Typ Ihrer selectedProgramTierCombo Variable ändern, da es sonst nicht kompiliert:

EDIT: Oops, da die Reihen auf priceProgram abhängt, müssen Sie eine weitere verschachtelte from Klausel, denke ich:

Dictionary<int, int> selectedProgramTierCombo = 
    (from mainTierID in doc.TierID 
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    from progTier in priceProgram.Tiers 
    where mainTierID == progTier.TierID 
    select new { priceProgram.ProgramID, progTier.TierID }) 
    .ToDictionary(x => x.ProgramID, x => x.TierID); 

Zumindest das ist, was ich denke, Sie wollen. Wenn Sie anstelle von List<int, int> (was nicht gültig ist) klären könnten, was Sie wirklich wollen, können wir weiter helfen.

Um ehrlich zu sein, es ist mir nicht klar, warum Sie progTier überhaupt verwenden - Sie wissen, dass progTier.TierID die gleiche wie mainTierID ist, und Sie verwenden es nicht abgesehen davon, dass ...

+0

Vielleicht meinte er (oder braucht) 'List >' unter der Annahme, dass 'x.ProgramID' kein eindeutiger Bezeichner für die Zwecke dieser Sammlung war? Es würde die Antwort jedoch nicht stark ändern. –

+0

@Anthony: Möglicherweise. Es ist schwer zu sagen :( –

+0

Ich dachte daran, dies mit einem Join vor Ihrem Kommentar zu nähern. Jemand erwähnte SelectMany(), die ich nie verwendet habe, ist dies keine praktikable Lösung?Außerdem kümmere ich mich normalerweise nicht um das Casting, sondern stemple das ganze Ding in eine Var, besonders wenn die Strukturen den Funktionsblock nie verlassen. Dies ist nur eine Frage des Stils, kann aber für das Poster nützlich sein. – Sprague

2

Jons Antwort ist die richtige Idee, muss nur neu angeordnet werden, um zu kompilieren. Hier sind zwei Optionen.

var dict = (from mainTierID in doc.TierID 
      join f in 
       (from priceProgram in doc.CommitmentProgram.PricingPrograms 
        from progTier in priceProgram.Tiers 
        select new { priceProgram.ProgramID, progTier.TierID }) 
       on mainTierID equals f.TierID 
      select f).ToDictionary(f => f.ProgramID, f => f.TierID); 


var dict2 = (from priceProgram in doc.CommitmentProgram.PricingPrograms 
       from progTier in priceProgram.Tiers 
       join mainTierID in doc.TierID on progTier.TierID equals mainTierID 
       select new { priceProgram.ProgramID, progTier.TierID }) 
      .ToDictionary(x => x.ProgramID, x => x.TierID); 
+0

Danke Anthony. Die erste Variation half wirklich zu klären, was im Code vor sich geht =) – Robert

1

Die einzige Art von Bugs mich, aber ich muss gehen mit was gefragt wird.

Dictionary<int, int> selectedProgramTierCombo = 
(
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    let tierId = 
    (
    from progTier in priceProgram.Tiers 
    where doc.TierID.Any(mainTierID => mainTierID == progTier.TierID) 
    select progTier.TierID 
).Single() 
    select new 
    { 
    ProgramID = priceProgram.ProgramID, 
    TierID = tierID 
    } 
).ToDictionary(x => x.ProgramID, x => x.TierID); 

Dies ist, was ich mit bequemer sein würde:

ILookup<int, int> selectedProgramTierCombo = 
(
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    from progTier in priceProgram.Tiers 
    where doc.TierID.Any(mainTierID => mainTierID == progTier.TierID) 
    select new 
    { 
    ProgramID = priceProgram.ProgramID, 
    TierID = progTier.TierID 
    } 
).ToLookup(x => x.ProgramID, x => x.TierID); 
+0

Danke David. Gibt es einen bestimmten Grund, warum Sie ILookup anstelle von Dictionary verwenden? Wenn ja, würde ich gerne wissen warum. – Robert

+0

Da in doc.TierID möglicherweise mehr als ein Element vorhanden ist und in priceProgram.Tiers mehr als eine übereinstimmende Ebene vorhanden sein kann, kann ein bestimmtes Preisprogramm mehrere Hauptstufen haben (zumindest im technischen Sinne). ILookup ermöglicht mir mehrere Werte für einen Schlüssel. –

+0

Sinn machen. Vielen Dank! – Robert

Verwandte Themen