Reputation: 57805
I have the following entities set up which I am trying to query:
Store -[m2m]- StoreCapability -[m2m]- Offer
So there are five tables involved.
I would like to be able to obtain the following using linq:
Using SQL it would be possible to join from Store, to StoreCapability, to Offer and then group by offer and store and only obtain the stores having count() equal to the number of requirements an offer has. However I don't know where to start with this with Linq, because the many-many tables are hidden away from me by the Entity framework. Please can anyone help with how I can do this?
The SQL could be something similar to this:
SELECT Offers.Id, offers.Name, Stores.Id, Stores.Name FROM Offers
--join to the capabilities that this offer needs
LEFT OUTER JOIN StoreCapabilityOffers offerRequirements ON Offers.Id = offerRequirements.Offer_Id
--join to stores which have capability
LEFT OUTER JOIN StoreCapabilities ON offerRequirements.StoreCapability_Id = StoreCapabilities.Id
--join to stores
LEFT OUTER JOIN StoreStoreCapabilities storeCap ON offerRequirements.StoreCapability_Id = storeCap.StoreCapability_Id
LEFT OUTER JOIN Stores on storeCap.Store_Id = Stores.Id
GROUP BY Offers.Id, offers.Name, Stores.Id, Stores.Name
-- get stores who have the right number of capabilities so all requirements are all met
HAVING COUNT(*) = (
select COUNT(*) from StoreCapabilityOffers x where x.Offer_Id = Offers.Id
)
Entities below:
public class Store
{
public int Id { get; set; }
public virtual ICollection<StoreCapability> Capabilities { get; set; }
}
public class StoreCapability
{
public int Id { get; set; }
public virtual ICollection<Store> Stores { get; set; }
public virtual ICollection<Offer> Offers { get; set; }
}
public class Offer
{
public int Id { get; set; }
public virtual ICollection<StoreCapability> StoreCapabilityRequirements { get; set; }
}
Upvotes: 0
Views: 1432
Reputation: 364249
I think something like this should work:
Given an offer, a list of stores which it is valid for:
var stores = from o in context.Offers
from c in o.StoreCapabilityRequirements
from s in c.Stores
where o.Id == 1
select s;
Given a store, a list of offers available:
var offers = from s in context.Stores
from c in s.Capabilities
from o in c.Offers
where s.Id == 1
select o;
Upvotes: 1