Reputation: 12621
I have the following three tables:
alt text http://img16.imageshack.us/img16/5499/linqtosqlquery.jpg
With LinqToSql I would like to retrieve a list of InventoryItems where (pointsName="Level" AND pointsValue <= maxStoreLevel) AND pointsName="Buy Price" and
Note that maxStoreLevel
is an Integer and it is the value of the points row that has pointsName = "Level".
Since you can't use a where inside another where in Linq, I do not know how to go about retrieving the mentioned list.
Update: Here is the UML diagram as requested
alt text http://img17.imageshack.us/img17/3403/umldiagram.jpg
To further explain my scenario here's the data in my tables:
alt text http://img4.imageshack.us/img4/7847/linqexample.jpg
Assuming maxStoreLevel is 1, "Hanzo's Helmet" has pointsValue = 1 where pointsName="Level" and also has a point called "Buy Price" therefore it's row should be returned (same goes with any other Inventoryitems with the same criteria)
Upvotes: 1
Views: 144
Reputation: 9100
OK, so this isn't as pretty as the lambda expressions and I'm still a little fuzzy on what exactly the where clause needs to be since PointsName can't be Level and Buy Price at the same time, but I needed to start the conversation somewhere. I'm guessing that you'll need to do 2 joins on the points table but since you know your setup better than I, I'm guessing you'll be able to take this and modify it as needed. Let me know what I'm missing...
var items = (From items in context.InventoryItems
join itemPoints in context.InventoryItemPoints on items.InventoryItemID equals itemPoints.InventoryItemID
join points in context.Points on itemPoints.pointsID equals points.pointsID
where (points.pointsName == "Level" && itemPoints.pointsValue == maxStoreLevel) && points.pointsName == "Buy Price"
select items).Distinct();
I knew the original wouldn't return rows as there was no way for the points name to have both values but based off your subsequent update, I think what you need is:
var items = (From items in context.InventoryItems
join levelItemPoints in context.InventoryItemPoints on items.InventoryItemID equals levelItemPoints.InventoryItemID
join levelPoints in context.Points on levelItemPoints.pointsID equals levelPoints.pointsID
join priceItemPoints in context.InventoryItemPoints on items.InventoryItemID equals priceItemPoints.InventoryItemID
join pricePoints in context.Points on priceItemPoints.pointsID equals pricePoints.pointsID
where (levelPoints.pointsName == "Level" && levelItemPoints.pointsValue == maxStoreLevel) && pricePoints.pointsName == "Buy Price"
select items).Distinct();
Upvotes: 1
Reputation: 12768
While you can't double where clauses, you can use sub-selects and use Count to see that they contain values. Try:
var items = from item in context.InventoryItems
where (from iip in context.InventoryItemPoints
join p in context.Points on p.pointsId equals iip.pointsId
where iip.InventoryItemId == item.InventoryItemId
&& p.pointsName == "Level" && iip.pointsValue == maxStoreLevel
select iip).Count() > 0
&& (from iip in context.InventoryItemPoints
join p in context.Points on p.pointsId equals iip.pointsId
where iip.InventoryItemId == item.InventoryItemId
&& p.pointsName == "Buy Price"
select iip).Count() > 0
select item;
Upvotes: 0
Reputation: 3417
Something like:
var items = inventoryItems.Where(
invItem => invItem.InventoryItemPoints.Contains(
iip => (iip.pointsName == "Buy Price" || iip.PointsName == "Level") &&
iip.pointsValue == maxStoreLevel);
but that's a bit of a guess based on what you've posted, if that's not it, a screenie of the dbml would be useful ;)
Update: OK - that's clearly rubbish (sorry, couple of glasses of wine too many :)
try this:
var items = dataContext.inventoryItems.Where(
invItem => ivnItem.InventoryItemPoints.Select(
iip => iip.Point.PointName).Contains(
"Buy Price")
&& invItem.InventoryItemPoints.Select(
iip => iip.pointsValue).Contains(maxStoreLevel));
Adding in the other pointNames should be easy enough...
Upvotes: 0