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...
offeredPlans .Add(new Tuple<int, string>(providerId, plan.Name));
}
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?
- 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<int, string>(providerId, plan.Name));
}
1 Answer 1
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);
-
\$\begingroup\$ 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 \$\endgroup\$mitomed– mitomed2013年04月19日 22:24:57 +00:00Commented Apr 19, 2013 at 22:24
-
\$\begingroup\$ 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? \$\endgroup\$mitomed– mitomed2013年04月19日 22:35:16 +00:00Commented Apr 19, 2013 at 22:35
-
\$\begingroup\$ @mitomed Nah, it's not that bad. See my updated answer. \$\endgroup\$p.s.w.g– p.s.w.g2013年04月19日 22:41:05 +00:00Commented Apr 19, 2013 at 22:41
-
\$\begingroup\$ 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 \$\endgroup\$mitomed– mitomed2013年04月19日 22:59:16 +00:00Commented Apr 19, 2013 at 22:59