List<int> ListIdProducts = new List<int>();
var IdProductKey = from a in me.ProductKeywords where a.Keyword == item.Id select a;
foreach (var item2 in IdProductKey)
{
ListIdProducts.Add(item2.Product.Value);
}
Result is:
5
6
7
5
2
5
I need to get the following 5=3, 6=1, 7=1, 2=1
Use GroupBy LINQ method:
ListIdProducts
.GroupBy(i => i)
.Select(g => new { Value = g.Key, Count = g.Count() });
var query1 = from a in ListIdProducts
group a by new { a } into g
select new
{
item = g.Key,
itemcount = g.Count()
};
This a fairly standard group-by problem.
//untested
var IdProducts = from a in me.ProductKeywords
where a.Keyword == item.Id
group by a.Product.Value into g
select g.Count();
Related
What could be the LINQ query for this SQL?
SELECT PartId, BSId,
COUNT(PartId), MAX(EffectiveDateUtc)
FROM PartCostConfig (NOLOCK)
GROUP BY PartId, BSId
HAVING COUNT(PartId) > 1
I am actually grouping by two columns and trying to retrieve max EffectiveDateUtc for each part.
This is what I could write. Stuck up on pulling the top record based on the date.
Also not sure, if this is a optimal one.
//Get all the parts which have more than ONE active record with the pat
//effective date and for the same BSId
var filters = (from p in configs
?.GroupBy(w => new
{
w.PartId,
w.BSId
})
?.Select(g => new
{
PartId = g.Key.PartId,
BSId = g.Key.BSId,
Count = g.Count()
})
?.Where(y => y.Count > 1)
select p)
?.Distinct()?.ToList();
var filteredData = (from p in configs
join f in filters on p.PartId equals f.PartId
select new Config
{
Id = p.Id,
PartId = p.PartId,
BSId = p.BSId,
//EffectiveDateUtc = MAX(??)
}).OrderByDescending(x => x.EffectiveDateUtc).GroupBy(g => new { g.PartId, g.BSId }).ToList();
NOTE: I need the top record (based on date) for each part. Was trying to see if I can avoid for loop.
The equivalent query would be:
var query =
from p in db.PartCostConfig
group p by new { p.PartId, p.BSId } into g
let count = g.Count()
where count > 1
select new
{
g.Key.PartId,
g.Key.BSId,
Count = count,
EffectiveDate = g.Max(x => x.EffectiveDateUtc),
};
If I understand well, you are trying to achieve something like this:
var query=configs.GroupBy(w => new{ w.PartId, w.BSId})
.Where(g=>g.Count()>1)
.Select(g=>new
{
g.Key.PartId,
g.Key.BSId,
Count = g.Count(),
EffectiveDate = g.Max(x => x.EffectiveDateUtc)
});
I have a list in my code that I need to filter through and return specific rows based on two criteria. The List in question is a list of models from a database. There are two ID properties on each model, one is the ID from the data table and is unique, the other is an ID we use to identify groups and can repeat. We'll call them ID and GroupID. Basically, I want the resulting list to have only one of each GroupID, and it should be the one with the highest (numerically speaking) ID. For example:
Input:
List<MyModel> modelList = new List<MyModel>
modelList[0].ID = 1 modelList[0].GroupID = 5
modelList[1].ID = 2 modelList[1].GroupID = 5
modelList[2].ID = 3 modelList[2].GroupID = 6
modelList[3].ID = 4 modelList[3].GroupID = 6
Desired Output:
Models at indexes 1 and 3.
Using LINQ:
var items = (from model in modelList
group model by model.GroupID into modelGroup
select modelGroup.Max(i => i.ID)).ToList();
What you have to do here is first order the modelList by ID and then GroupBy the list items by GroupID, then pull the item with max Id value.
var result = modelList.OrderByDescending(x => x.ID).GroupBy(x => x.GroupID).Select(x => x.First());
the above query will give you the result.
This is your solution:
var myData = models.GroupBy(model => model.GroupId)
.Select(group => group.OrderByDescending(model => model.Id).First());
Or you could also do this:
var myData = models.GroupBy(model => model.GroupId)
.Select(group => group.First(model => model.Id == group.Max(model1 => model1.Id)));
For fun, here's a fiddle.
You can try to use GroupBy.
var q = modelList.GroupBy(x => x.GroupID, x => x,
(key, g) => new {
GroupID = key,
Id = g.Max(c => c.ID)
});
This should group all your elements by GroupId and select Max ID in one of that groups.
Try this code:
List<MyModel> modelList = new List<MyModel>();
modelList.Add(new MyModel());
modelList.Add(new MyModel());
modelList.Add(new MyModel());
modelList.Add(new MyModel());
modelList[0].ID = 1; modelList[0].GroupID = 5;
modelList[1].ID = 2; modelList[1].GroupID = 5;
modelList[2].ID = 3; modelList[2].GroupID = 6;
modelList[3].ID = 4; modelList[3].GroupID = 6;
var list = from ml in modelList group ml by ml.ID into r select new { ID = r.Key, MaxGroupID = r.Max() };
this might help you
modelList.GroupBy(model => model.GroupId, g => g.Id).Select(item => item.Max())
var newModelList = modelList.GroupBy(ml => ml.GroupID)
.Select(g => new MyModel
{
ID = g.OrderByDescending(x => x.ID).First().ID,
GroupID = g.Key
}).ToList();
Details
1) GroupBy then Select to get distinct items over GroupID.
2) First() after OrderByDescending to get highest ID.
3) new MyModel in Select is just to be explicit about the projection.
This question already has answers here:
Group By Multiple Columns
(14 answers)
Closed 6 years ago.
Trying to group by multiple fileds but having issues with it. I want to group by period,productcode.
var ProductUsageSummary = from b in myProductUsage
group b by b.ProductCode into g
select new
{
Period = g.Key,
Code = g.Key,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
also tried
var ProductUsageSummary = from b in myProductUsage
group b by b.Period b.ProductCode into g
select new
{
Period = g.Key(n => n.period),
Code = g.Key,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
You could create an anonymouns object to to group on multiple columns (ex... new {prop1 prop2}) , and the grouped fields can be accessed by Key.PropertyName
Try this.
var ProductUsageSummary = from b in myProductUsage
group b by new { b.Period, b.ProductCode }into g
select new
{
Period= g.Key.Period,
Code = g.Key.ProductCode ,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
This is the correct syntax using Anonymous Types :
group b by new { b.ProductCode, b.Period } into g
Then in select:
g.Key.ProductCode and g.Key.Period
Full Query:
var ProductUsageSummary = from b in myProductUsage
group b by new { b.Period b.ProductCode } into g
select new
{
Period = g.Key.Period,
Code = g.Key.ProductCode,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
I have a string array of names or could be a List of names which can have multiple duplicate names. What I want to do is to get a list of top 5 most duplicate names. Could someone tell me what's the best way to do this?
Array[0] = 'Mike'
Array[1] = 'Tim'
Array[2] = 'Debra'
Array[3] = 'Mike'
Array[4] = 'Steve'
Array[5] = 'Mike'
Array[6] = 'Amy'
Array[7] = 'Tim'
Array[8] = 'Debra'
Array[9] = 'Amy'
Output: Mike has 3
Tim has 2
Debra has 2
Steve has 1
Amy has 1
Here is how it can be done with grouping:
var result = from name in namesArray
group name by name into g
orderby g.Count() descending
select new { Name = g.Key, Count = g.Count() };
If you need just top 5 - call .Take(5) of that:
var result = (from name in namesArray
group name by name into g
orderby g.Count() descending
select new { Name = g.Key, Count = g.Count() }).Take(5);
The easiest way to do this is to use GroupBy.
var result = Array
.GroupBy(x => x)
.Select(x => new { Name = x.Key; Count = x.Count() })
.OrderByDescending(x => x.Count)
.Take(5);
Looks to me like you want to do something with Linq,
var results = from name in names
group name by name into nameGroup
let count = nameGroup.Count()
orderby count descending
take 5
select new {Value = name, Count = count};
After which you can format the contents of the results as you desire.
Simple line:
var x = (from a in arr select a).First();
Console.WriteLine(“First" + x);
How to convert to Lambda expression?
So you want to convert the LINQ query from using query syntax to plain extension method calls?
// var first = (from a in arr select a).First();
var first = arr.First();
// var last = (from a in arr select a).Last();
var last = arr.Last();
// var filtered = (from a in arr where a == 10 select a).First();
// there are a couple of ways to write this:
var filtered1 = arr.Where(a => a == 10)
.First();
var filtered2 = arr.First(a => a == 10); // produces the same result but obtained differently
// now a very complex query (leaving out the type details)
// var query = from a in arr1
// join b in arr2 on a.SomeValue equals b.AnotherValue
// group new { a.Name, Value = a.SomeValue, b.Date }
// by new { a.Name, a.Group } into g
// orderby g.Key.Name, g.Key.Group descending
// select new { g.Key.Name, Count = g.Count() };
var query = arr1.Join(arr2,
a => a.SomeValue,
b => b.AnotherValue,
(a, b) => new { a, b })
.GroupBy(x => new { x.a.Name, x.a.Group },
x => new { x.a.Name, Value = x.a.SomeValue, x.b.Date })
.OrderBy(g => g.Key.Name)
.ThenByDescending(g => g.Key.Group)
.Select(g => new { g.Key.Name, Count = g.Count() });
When you have an expression of the form (from y in x select y), you can almost always write x instead.