# 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<Tuple<int, string>>();
foreach (var plan in plans)
{
// ....Some code...
}

var compareTo = offeringPlans.ToLookup(pair => pair.Item1, pair => 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<string> Check(int providerId, ILookup<int, string> plans)
{
return offeringPlans.Where(p => p.Key == providerId).SelectMany(p => p);
}


Is this terrible or does it make sense?

1. I've never used before these classes (Tuple, Lookup...)
2. 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;

}


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<int, string> plansLookup = ...
IEnumerable<string> plansForProvider = plansLookup[providerId]; // Finds all plans for this provider


However, it's not clear that you need to be creating the List<Tuple<int, string>> 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 => x.ProviderId, x => x.Name);

• Yes, I pasted the code before checking it as I thought it was relevant. But you're completely right I can create it from scratch – mitomed Apr 19 '13 at 22:24
• Maybe I talked too early in the last comment, I think in this case either it's not possible or it would be a very convoluted expression, right? – mitomed Apr 19 '13 at 22:35
• @mitomed Nah, it's not that bad. See my updated answer. – p.s.w.g Apr 19 '13 at 22:41
• Agreed, apart from a small typo (for instead of from) it works perfectly fine and it's not as terrible as I imagined (fear I had as never got into queries using lets). Thanks very much, I really think you've improved the code a lot – mitomed Apr 19 '13 at 22:59