Any value in the list - in LINQ - c#

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.

Related

List variable inside a query Linq

I have created a variable that returns a list ids of menus from the database. I have then put the variable in another query that returns meals in a list. My issue is that I keep on recieving the error Cannot implicitly convert type System.Collections.Generic.List<int?> to int?
var getmenuids = (from r in db.Menus
where (r.Restaurantid == currentrestaurant)
select r.Id).ToList();
var meals = db.Meals.Where(r => r.MenuID = getmenuids).ToList();
You're having an issue because you're using == (comparing a single element to a list) instead of Contains() (searching for the an element in the list).
var meals = db.Meals.Where(r => getmenuids.Contains(r.MenuID)).ToList();
You could combine these too.. something like this:
var meals = (from meal in db.Meals
join menu in db.Menus on meal.MenuID equals menu.Id
where menu.Restaurantid == currentrestaurant
select meal).ToList();
The problem here is that getmenuids is a collection of int? values but you compare it to r.MenuID which is typed to int?. To fix this you need to search getmenuids for r.MenuId
db.Meals.Where(r => getmenuids.Contains(r.MenuID)).ToList();
You are comparing the list with MenuID. getmenuids is a list.
r.MenuID = getmenuids

Splitting Linq List by grouping

for reporting purposes i wanna split a list of purchase orders into multiple lists. One list for each purchase address. I know it's possible to group the list by purchase address, but my question is how to split the list by this purchase address into multiple lists and use these multiple list to create individual reporting files.
code:
(from o in orders
group o by new {field1, field2, field3, field4} into og
orderby og.Key.field1
select new ViewClass
{
purchaseAddress = og.Key.field1,
product = og.key.field2,
count = og.count
}).ToList()
question: how to split above list into multiple lists for each purchaseAddress?
There's a built-in function that I think does what you want. If I assume that your code is assigned to a variable called query then you can write this:
ILookup<string, ViewClass> queryLists = query.ToLookup(x => x.purchaseAddress);
This essentially creates a list of lists that you access like a dictionary, except that each value is a list of zero or more values. Something like:
IEnumerable<ViewClass> someList = queryLists["Some Address"];
Just turn each group into a List.
select new ViewClass
{
purchaseAddress = og.Key.field1,
product = og.key.field2,
count = og.count,
List = og.ToList()
}).ToList();
Oh, your grouping is one way for entities and another way for pages... just regroup.
List<ViewClass> classes = (
from o in orders
group o by new {field1, field2, field3, field4} into og
orderby og.Key.field1
select new ViewClass
{
purchaseAddress = og.Key.field1,
product = og.key.field2,
count = og.count
}).ToList();
List<List<ViewClass>> regrouped = (
from c in classes
group c by c.purchaseAddress into g
select g.ToList()
).ToList();
Another simple built-in function that you can use is the GroupBy function. It does a similar job as the ToLookup but it means that your new list is IQuerable, not like a dictionary and a few other things (see this article for a good breakdown)
var newList = orders.GroupBy(x => x.field1);
This will return a list of lists grouped by the field(s) you specify.

C#, lambda, linq

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();

grouping and counting in linq-to-sql

I have the following query that receives a list of IDs and I want to do a count. There's also an object model CountModel that holds the counts with each property defined as an int.
public class GetCountByStatus(List<int> TheIDs)
{
...using MyDC...
var CountData = (from d in MyDC.Data
where TheIDs.Contains(d.ID)
group d by d.Status into statusgroup
select new CountModel()
{
CountStatus1 = (from g in statusgroup
where g.Status == 1
select g).Count(),
CountStatus2 = (from g in statusgroup
where g.Status == 2
select g).Count(),
CountStatusN = ....
}).Single();
If for instance there are no elements with status N, will this code crash or will the count be 0 for CountStatusN ? Is this the best way to do what I want?
Thanks.
I would go for a dictionary instead, try something like this:
var countData = MyDC.Data.Where(y => TheIDs.Contains(y.ID))
.GroupBy(y => y.Status).ToDictionary(y => y.Key, y => y.Count());
I haven't tried it my self and not written the code in VS, but I think that is almost how you do can do it. That will give you a dictionary where the key is the status and the value is the count of that status.
Defining a model with properties named SomethingX is not very flexible. That means you have to go in an change the model when there is a new status. Keeping the data in the dictionary instead will save you from that.
Count() will always return an integer, which is 0 if there are no elements with the given status. Therefore CountStatusN will always be an integer as well.

How to cast a Linq Dynamic Query result as a custom class?

Normally, I do this:
var a = from p in db.Products
where p.ProductType == "Tee Shirt"
group p by p.ProductColor into g
select new Category {
PropertyType = g.Key,
Count = g.Count() }
But I have code like this:
var a = Products
.Where("ProductType == #0", "Tee Shirt")
.GroupBy("ProductColor", "it")
.Select("new ( Key, it.Count() as int )");
What syntax could I alter to produce identical results, i.e., how do I do a projection of Category from the second Linq statement?
I know in both that g and it are the same and represent the entire table record, and that I am pulling the entire record in just to do a count. I need to fix that too. Edit: Marcelo Cantos pointed out that Linq is smart enough to not pull unnecessary data. Thanks!
Why would you have to do it at all? Since you still have all of the information after the GroupBy call, you can easily do this:
var a = Products
.Where("ProductType == #0", "Tee Shirt")
.GroupBy("ProductColor", "it")
.Select(c => new Category {
PropertyType = g.Key, Count = g.Count()
});
The type of Products should still flow through and be accessible and the regular groupings/filtering shouldn't mutate the type that is flowing through the extension methods.

Categories

Resources