Group BY multiple using linq [duplicate] - c#

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

Related

LINQ Query with GroupBy, MAX and Count

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

Translating Linq expression in c#

I am trying to convert this code:
var query2 = from b in db.MU_Reports
join downtime in db.Downtime_Reports on b.Shift equals downtime.Shift
where downtime.Downtime_Code.Equals("9185")
group downtime by new { b.Date, b.Shift, b.Machine_Number, b.MU } into g
select new
{
Date = g.Key.Date,
Shift = g.Key.Shift,
Machine = g.Key.Machine_Number,
MU = g.Key.MU,
No_Work_Hours = g.Sum(x => x.Total_DownTime)
};
To look something like this one:
var query = db.MU_Reports.Join(db.Downtime_Reports, b=> b.Shift, c=> c.Shift, (b , c) => new { b, thisshift = c })
.Where(n => n.thisshift.Down_TIme_Codes.Equals("9185"))
.GroupBy(d=> new { d.b.Date, d.b.Shift, d.b.Machine_Number, d.b.MU }, d => d.b)
.Select (g=> new
{
Date = g.Key.Date,
Shift = g.Key.Shift,
Machine = g.Key.Machine_Number,
MU = g.Key.MU,
No_Work_Hours = g.Sum(i => i.Total_DownTime)
}).ToList();
As you can see I am very close. My only issue is the last statement No_Work_Hours = g.Sum(i => i.Total_DownTime) It is trying to get the Total_DownTime from db.MU_Reports but it needs to come from db.Downtime_Reports. I am new to c# and am doing this to understand the program I created better.
Your second argument to GroupBy should be d => d.thisshift instead of d => d.b. That corresponds to the group downtime by, but by doing d => d.b it's like you're doing group b by
var query = db.MU_Reports
.Join(
db.Downtime_Reports,
b=> b.Shift,
c=> c.Shift,
(b , c) => new { b, thisshift = c })
.Where(n => n.thisshift.Down_TIme_Codes.Equals("9185"))
.GroupBy(
d=> new { d.b.Date, d.b.Shift, d.b.Machine_Number, d.b.MU },
d => d.thisshift)
.Select (g=> new
{
Date = g.Key.Date,
Shift = g.Key.Shift,
Machine = g.Key.Machine_Number,
MU = g.Key.MU,
No_Work_Hours = g.Sum(i => i.Total_DownTime)
})
.ToList();

LINQ with grouping and summation

I need to group on dept and needWeek and then add sum together, add open together, and add closed together.
This query:
var query8 = from q8 in query7
group q8 by new { q8.q7.dept, q8.needWeek, q8.q7.allCount, q8.q7.openCount, q8.q7.closedCount } into g
select new
{
dept = g.Key.dept,
needWeek = g.Key.needWeek,
sum = g.Sum(q8 => g.Key.allCount),
open = g.Sum(q8 => g.Key.openCount),
closed = g.Sum(q8 => g.Key.closedCount)
};
will return:
{ dept = foo, needWeek = 05/20/12, sum = 7, open = 3, closed = 4 }
{ dept = foo, needWeek = 05/20/12, sum = 2, open = 0, closed = 2 }
but I need:
{ dept = foo, needWeek = 05/20/12, sum = 9, open = 3, closed = 6 }
How close am I?
You are close, but you're grouping by all unnecessary fields. Just group by what is common to all.
var query8 =
from q8 in query7
group new { q8.q7.allCount, q8.q7.openCount, q8.q7.closedCount }
by new { q8.q7.dept, q8.needWeek }
into g
select new
{
g.Key.dept,
g.Key.needWeek,
sum = g.Sum(x => x.allCount),
open = g.Sum(x => x.openCount),
closed = g.Sum(x => x.closedCount),
};
I need to group on dept and needWeek
So why doesn't your code follow your needs? Why are you grouping by everything?
group q8 by new { q8.q7.dept, q8.needWeek } into g
select new
{
dept = g.Key.dept,
needWeek = g.Key.needWeek,
sum = g.Sum(q8 => g.q7.allCount),
open = g.Sum(q8 => g.q7.openCount),
closed = g.Sum(q8 => g.q7.closedCount)
};

Linq syntax c# to select two field from table

i am writing the following linq code in c#
var groupedData = from b in dt.AsEnumerable()
group b by b.Field<string>("TypeColor") into g
select new
{
Key = g.Key,
Value = g.Select(r => r.Field<int>("Price")),
Price = g.Select(r => r.Field<int>("Price"))
};
foreach (var g in groupedData)
{
string s = g.Key;
}
how can i select two or more field from the datatable and group the table with one field.
Can any body help me?
Here dt is a datatable which is binding from database
You need to aggregate the fields if you've grouped the rows(similar as in SQL):
var groupedData = from b in dt.AsEnumerable()
group b by b.Field<string>("TypeColor") into g
select new
{
Color = g.Key,
PriceSum = g.Sum(r => r.Field<int>("Price")),
FirstValue = g.First().Field<int>("Value")
};
foreach (var g in groupedData)
{
string color = g.Color;
Double priceSum = g.PriceSum;
int firstValue = g.FirstValue;
}

how to get the number of repetitions from List<int>

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

Categories

Resources