Tuple/Lookup conundrum I have a list of plans and a list of contacts, and I have to check whether contact.ProviderId matches plan.ProviderId. If they match I need to store in a contactUI the plan.Name.

Provider to plan is a 0..1-to-many relationship, and that's why I couldn't use the Dictionary I tried at first instance.

For retrieving the list of object I need to call the DB. So I want to avoid calling it more than needed.

I came up with this

var offeredPlans = new List&lt;Tuple&lt;int, string&gt;&gt;();
foreach (var plan in plans)
{
    // ....Some code...
    offeredPlans .Add(new Tuple&lt;int, string&gt;(providerId, plan.Name));
}

var compareTo = offeringPlans.ToLookup(pair =&gt; pair.Item1, pair =&gt; pair.Item2);

foreach(var contact in contacts)
{
    var plansAttachedTo = Check(providerId.Value, compareTo);

    foreach (var plan in plansAttachedTo)
    {
        // New contactUI with plan.Name as one of its properties 
    }
}


Being 

private static IEnumerable&lt;string&gt; Check(int providerId, ILookup&lt;int, string&gt; plans)
{
    return offeringPlans.Where(p =&gt; p.Key == providerId).SelectMany(p =&gt; p);
}


Is this terrible or does it make sense?


I've never used before these classes (Tuple, Lookup...)
I would like my code to be the clearest I can even it it's not the cleverest of the solution I can think of which is not this case for sure, actually I realize now I could have done some kind of SQL joins, right? (but I would like to know if someone can point any obvious error in the current code).


Edit

The code inside the loop is this one (in this case I don't even omit code as I'm not sure if it's possible what you suggest p.s.w.g). I am using reflection as only some of the classes that inherit from plan have the ProviderId property.

foreach (var plan in plans)
{
    var offeringDetail = new OfferingDetail();

    if (plan.GetType() == typeof (OwnedProductSummary))
    {
        var productSummary = plan as OwnedProductSummary;

        offeringDetail = _offeringBLL.GetById(productSummary.OfferingID);
    }

    if (plan.GetType() == typeof (OwnedServiceSummary))
    {
        var serviceSummary = plan as OwnedServiceSummary;

        offeringDetail = _offeringBLL.GetById(serviceSummary.OfferingID);
    }

    // For the other types of summary will be 0
    var providerId = offeringDetail.ProviderID;

    offeredPlans .Add(new Tuple&lt;int, string&gt;(providerId, plan.Name));
}
Once you've gotten your code into a ILookup you can just call Item property (which in C# is called with [...]) to get all values with a given key. So the Check can be entirely replaced by using the ILookup like this:

ILookup&lt;int, string&gt; plansLookup = ...
IEnumerable&lt;string&gt; plansForProvider = plansLookup[providerId]; // Finds all plans for this provider


However, it's not clear that you need to be creating the List&lt;Tuple&lt;int, string&gt;&gt; in the first place. You can just use Linq to generate your ILookup from scratch:

var plansLookup = 
    (from plan in plans
     let productSummary = plan as OwnedProductSummary
     let serviceSummary = plan as OwnedServiceSummary
     let offeringDetail =
         (productSummary != null) ? _offeringBLL.GetById(productSummary.OfferingID) :
         (serviceSummary != null) ? _offeringBLL.GetById(serviceSummary.OfferingID) :
         new OfferingDetail()
     select new 
     {
         offeringDetail.ProviderID,
         plan.Name
     })
    .ToLookup(x =&gt; x.ProviderId, x =&gt; x.Name);