C#, lambda, linq - c#

Say I have an int list that contains a list of ids. I have a linq table and I want to return a particular column but only where the ID of the linq table is equal to any of the ID's in the int list.
So far I have:
dc.tb_References.SelectMany(n => n.ID == ids).ToList();
In sql I would just write:
SELECT Column_Name from Table where ID in (1,2,3,4)
I have been googling but I can't find what I'm looking for. Does anyone have any tips? I would like to stick with lambda expressions.

You can use Contains() method on ID list.
dc.tb_References.Where(item => ids.Contains(item.ID)).ToList();

Try this
dc.tb_References.Where(n => ids.Contains(n.ID)).ToList();

Use the Where method with the Contains method:
dc.tb_References
.Where(n => theListOfIds.Contains(n.ID))
.Select(x => x.Column_Name)
.ToList();
or you can do:
var query = from item in dc.tb_References
where theListOfIds.Contains(item.ID)
select item.Column_Name;
var list = query.ToList();
SelectMany is used to select items from a sub-list and then retun all these ites as a list:
Fruit.Items: Apple, Pear
Veggies.Items: Carrot, Cabbage
List.Items: Fruit, Veggies
List.Items.SelectMany(x => x.Items)
Result:
Apple, Pear, Carrot, Cabbage

Is this the kind of thing you're after?
int[] myIds = {1,4,5,3};
List<int> list = new List<int>();
list.Add(1);
list.Add(5);
list.Add(8);
list.Add(9);
list.Add(10);
list.Add(12);
List<int> select = (from l in list where myIds.Contains(l) select l).ToList();

To generate IN clause you need to call the Contains method on the collection and pass that method the property of the object you want to search for:
var ids = new int[] { 1, 3 };
var query = from n in dc.tb_References
where ids.Contains(n.ID)
select n;
Here is generated SQL (from LinqPad):
DECLARE #p0 Int = 1
DECLARE #p1 Int = 3
SELECT [t0].[ID], [t0].[Foo], [t0].[Bar]
FROM [tb_References] AS [t0]
WHERE [t0].[ID] IN (#p0, #p1)

int ids = new int[]{1,2,3,4};
var list = (from d in dc.tb_References
where ids. Contains(d.ID)
select d. Column_Name).ToList();

Related

Why do I need distinct with this LINQ query but not with SQL

Im getting a list of codes from a table and their respective count. I dont need to use distinct in SQL, but if I do not add this in the LINQ query, I get many dupe rows.
So, why would I need the distinct call on the LINQ query?
SQL
SELECT COUNT(*) AS ServiceCodeCnt, d.ServiceCode
FROM dbo.BackOrderItem d
GROUP BY d.ServiceCode, d.Model
HAVING d.Model ='UUTTIISJWW'
LINQ (via LINQpad)
void Main()
{
var retval = (from a in BackOrderItems where a.Model == "UUTTIISJWW"
group a by new {a.ServiceCode, a.Model} into grp1
from b in grp1
select new {Code = b.ServiceCode, Count = grp1.Count( ) }).ToList().Distinct();
retval.Dump();
}
The statement ...
from b in grp1
... flattens the grouping. So you select all individual rows in each group, each with the count of its group.
Just remove this statement, so it becomes:
var retval = (from a in BackOrderItems where a.Model == "UUTTIISJWW"
group a by a.ServiceCode into grp1
select new
{
Code = grp1.Key,
Count = grp1.Count()
})
.ToList();
Note that I also removed Model from the grouping. It's not necessary, because you only filter out one Model.

Linq select records that match a list of IDs

Is it possible to change my query below, so that it uses the types list within a contains type query.
So instead of having:
var cust = db.Customers.Where(x => x.type_id==9 || x.type_id==15 || x.type_id==16).ToList();
...I would have something like:
List<int> types = new List<int> { 9, 15, 16 };
var cust = db.Customers.Where(x => types.contains(x.type_id).ToList();
(type_id is not the primary key).
Thank you,
Mark
Yes, method List<T>.Contains will be translated into SQL IN operator:
var cust = db.Customers.Where(x => types.Contains(x.type_id)).ToList();
Generated query will look like:
SELECT * FROM Customers
WHERE type_id IN (#p0, #p1, #p2)

Any value in the list - in LINQ

I need to pull all values where the request type is any of the ones I have on the list.
from v in ctx.vEmailSents
where v.RequestType_ID == reqTypeID
group v by v.SentToLab_ID into g
select g.OrderByDescending(x => x.DateSent).FirstOrDefault() into lastV
select new
{
ClaimID = lastV.Claim_ID,
};
reqTypeID is of type List<int>.
How can I use it in Linq to get all records that are in that list?
You can do something like this:
where requestTypes.Contains(v.RequestType_ID)
requestTypes would be the list you talked about.

LINQ to SQL Query Against Bridge Table

I'm having problems with a LINQ to SQL query in the following scenario:
I have items that have "Tags" applied via a bridge table.
I'm trying to filter a list of items to a subset that contain all of a specified set of tags and return the filtered list of items as the query result.
Tables Involved:
Item (ItemId, Name, ...other fields)
Tag (TagId, TagName)
Item_Tag(ItemId, TagId)
As an example if I had a list of Items with tags:
Item1 w/ (Tag1, Tag2)
Item2 w/ (Tag1, Tag2)
Item3 w/ (Tag1)
and I wanted to get all items where the item has both Tag1 AND Tag2 where the filter requirement is provided as an int[] of the required tagIds.
Assuming the Item and Tag Id's match the number at the end of the name. The filter for this example would be:
int[] tagFilterConditions = int[2]{1, 2};
var query = from i in itemList
//define filter here
where the result would be:
Item1,Item2 (excludes Item 3 b/c it isn't tagged with Tag1 AND Tag2)
I'm having a tough time figuring out how to combine these tables to apply that filter on the source list, I've tried using a predicate builder and various joins but just can't get the correct results.
Thanks, for any help...
// Query for all the items in the list
int[] itemIds = itemList.Select(item => item.ItemId).AsArray();
var query =
db.Item.Where(item =>
itemIds.Contains(item.ItemId));
// Apply each tag condition
foreach (int tagid in tagFilterConditions)
{
int temp = tagid;
query = query.Where(item =>
db.Item_Tag.Exists(item_tag =>
item_tag.ItemId == item.ItemId && item_tag.TagId == temp)));
}
I think the answer to your question is in .Contains(): http://blog.wekeroad.com/2008/02/27/creating-in-queries-with-linq-to-sql
Here's what I think is the relevant snippet from that site to your question:
int[] productList = new int[] { 1, 2, 3, 4 };
var myProducts = from p in db.Products
where productList.Contains(p.ProductID)
select p;
Hope this helps!
Here is some sql.
and here is the LinqToSql..
Got the following query to work using an anonymous type after defining the proper foreign key relationships the query was adapted from an answer on this question.
//the tagId's that the item in itemList must have
int[] tagFilterConditions = int[2]{1, 2};
var query =
itemList.Select( i=> new { i, itemTags= item.Item_Tags.Select(it=> it.TagId)})
.Where( x=> tagFilterConditions.All( t=> x.itemTags.Contains(t)))
.Select(x=> x.s);

How do I get results from a Linq query in the order of IDs that I provide?

I'm looking to get query results back from Linq in the order that I pass IDs to the query. So it would look something like this:
var IDs = new int [] { 5, 20, 10 }
var items = from mytable in db.MyTable
where IDs.Contains(mytable.mytableID)
orderby // not sure what to do here
select mytable;
I'm hoping to get items in the order of IDs (5, 20, 10).
(Note this is similar to this question, but I would like to do it in Linq instead of SQL)
I would just do it outside of the SQL query. There's really no benefit to getting it done on the SQL Server in this case.
var items = (from mytable in db.MyTable
where IDs.Contains(mytable.mytableID)
select mytable)
.ToArray()
.OrderBy(x => Array.IndexOf(ids, x.mytableID));
This should work with LINQ-to-objects; I'm not sure if it does with LINQ-to-SQL though:
var ids = new int [] { 5, 20, 10 };
var result = from item in items
where Array.IndexOf(ids, item.Id) >= 0
orderby Array.IndexOf(ids, item.Id)
select item;

Categories

Resources