Linq version of SQL "IN" statement
I have the following 3 tables as part of a simple "item tagging" schema:
==Items==
- ItemId int
- Brand varchar
- Name varchar
- Price money
- Condition varchar
- Description varchar
- Active bit
==Tags==
- TagId int
- Name varchar
- Active bit
==TagMap==
- TagMapId int
- TagId int (fk)
- ItemId int (fk)
- Active bit
I want to write a LINQ query to bring back Items that match a list of tags (e.g. TagId = 2,3,4,7). In my application context, examples of items would be "Computer Monitor", "Dress Shirt", "Guitar", etc. and examples of tags would be "electronics", "clothing", etc. I would normally accomplish this with a SQL IN Statement.
Something like
var TagIds = new int[] {12, 32, 42};
var q = from map in Context.TagMaps
where TagIds.Contains(map.TagId)
select map.Items;
should do what you need. This will generate an In ( 12, 32, 42 ) clause (or more specifically a parameterized IN clause if I'm not mistaken).
given array of items:
var list = new int[] {2,3,4}
use:
where list.Contains(tm.TagId)
List<int> tagIds = new List<int>() {2, 3, 4, 7};
int tagIdCount = tagIds.Count;
//
// Items that have any of the tags
// (any item may have any of the tags, not necessarily all of them
//
var ItemsAnyTags = db.Items
.Where(item => item.TagMaps
.Any(tm => tagIds.Contains(tm.TagId))
);
//
// Items that have ALL of the tags
// (any item may have extra tags that are not mentioned).
//
var ItemIdsForAllTags = db.TagMap
.Where(tm => tagIds.Contains(tm.TagId))
.GroupBy(tm => tm.ItemId)
.Where(g => g.Count() == tagIdCount)
.Select(g => g.Key);
//
var ItemsWithAllTags = db.Items
.Where(item => ItemsIdsForAllTags.Contains(item.ItemId));
//runs just one query against the database
List<Item> result = ItemsWithAllTags.ToList();
You can simply use,
var TagIds = {12, 32, 42}
var prod =entities.TagMaps.Where(tagmaps=> TagIds .Contains(tagmaps.TagId));