.SelectMany with C# - c#

I found this post and I need something similar
stackoverflow.com/questions/41282053/groupby-multiple-date-properties-by-month-and-year-in-linq/43112774#43112774
I need to group by month and year, but at the same time I need a property of the main element, which I can not access
var departments = stops
.SelectMany(x => new[] { x.InitDate.Month, x.InitDate.Year }
.Where(dt => dt != null).Select(dt => x.InitDate))
.GroupBy(dt => new { dt.Month, dt.Year })
.OrderBy(g => g.Key.Month)
.ThenBy(g => g.Key.Year)
.Select(g => new
{
Key = g.Key.Month,
Año = g.Key.Year,
Duration = 0,
Count = g.Count()
});
I would need access to "stops.Duration" but if i do this: .SelectMany(x => new[] { x.InitDate.Month, x.InitDate.Year, x.Duration }
it does not group me by month-year
Can anybody help me?
Sorry for my english and thank you very much

This code should do:
var departments = stops
.Where(stop => stop.InitDate != null)
.SelectMany(stop => new[] { Month = stop.InitDate.Month, Year = stop.InitDate.Year, Duration = stop.Duration })
.GroupBy(dt => new { dt.Month, dt.Year })
.OrderBy(g => g.Key.Month)
.ThenBy(g => g.Key.Year)
.Select(g => new
{
Key = g.Key.Month,
Año = g.Key.Year,
Duration = g.Sum(v => v.Duration),
Count = g.Count()
});
It selects the duration, groups on month and year, and uses the sum of the duration from the grouped result.

int Month = 0, Year= 0, Duration = 0;
var departments = stops
.Where(stop => stop.InitDate != null)
.SelectMany(stop => new[] { Month = stop.InitDate.Month, Year = stop.InitDate.Year, Duration = stop.Duration })
.GroupBy(dt => new { Month, Year })
.OrderBy(g => g.Key.Month)
.ThenBy(g => g.Key.Year)
.Select(g => new
{
Key = g.Key.Month,
Año = g.Key.Year,
Duration = g.Sum(v => Duration),
Count = g.Count()
});
For me, this is the final solution

Related

How to use LINQ filter on a DataTable in Uipath

I have a Linq query written in C#. I don't know how to change it so that it works with UiPath.
The query finds all AccountNumber in the table and finds the sum of Remainder rows
var afterChange = listDate.GroupBy(account => account.AccountNumber)
.Select(group => new
{
AccountNumber = group.Key,
Сurrency = group.Select(groupElement => groupElement.Сurrency).First(),
Remainder = group.Select(groupElement => groupElement.Remainder).Sum(),
})
.AsEnumerable()
.Select(x => new TableData
{
Remainder = x.Remainder,
AccountNumber = x.AccountNumber,
Сurrency = x.Сurrency
})
.ToList();
Not familiar with UiPath, but your query needs correction.
var afterChange = listDate.GroupBy(account => new { account.AccountNumber, account.Сurrency })
.Select(group => new TableData
{
AccountNumber = group.Key.AccountNumber,
Сurrency = group.Key.Сurrency,
Remainder = group.Sum(x => x.Remainder),
})
.ToList();

Joining and selecting only the first item based on clause

I have a Customers and an Orders database.
I need to make some statistics for the first order of all new customers and count the number of first orders from new clients by month.`
var date = new DateTime(now.Year - 1, now.Month, 1);
db.Orders
.Where(o => o.Customer.IsNew && o.OrderDate > date)
.GroupBy(o => new { o.OrderDate.Year, o.OrderDate.Month })
.Select(g => new NewCustomerStatsModel {
Month = g.Key.Month,
Year = g.Key.Year,
Count = g.Count()
})
.OrderBy(cs => cs.Year)
.ThenBy(cs => cs.Month)
.ToList();
This query provide me the number of orders for all new client but I need to get only the sum of the first order for each new Customer if the first order date is greater than the provided date.
Is it possible to do it with a query (and how) or am I forced to use AsEnumerable and do it in memory?
I need to make some statistics for the first order of all new customers
var clientFirstOrders = db.Customers.Where(c => c.IsNew)
.Select(c => new{
Customer = c,
FirstOrder = c.Orders.OrderBy(c => c.OrderDate).FirstOrDefault()
})
// might have to do (int?)FirstOrder.Id != null or something like that.
.Where(e => e.FirstOrder != null);
and count the number of first orders from new clients by month.
var clientCountByFirstOrderMonth = clientFirstOrders
.GroupBy(e => new { e.FirstOrder.OrderDate.Year, e.FirstOrder.OrderDate.Month })
.Select(g => new{g.Key.Year, g.Key.Month, Count = g.Count()});
I could find the solution.
With some appropriate index, the performances are pretty good.
It's probably not a perfect solution, but I couldn't update the entities because it's not my Library.
var date = new DateTime(now.Year - 1, now.Month, 1);
var result = db.Orders
.Where(o => o.Customer.IsNew && o.State != OrderState.Cancelled) // get all orders where the Customer is a new one.
.GroupBy(o => o.Customer.Id) // group by customer
.Select(g => g.OrderBy(o => o.OrderDate).FirstOrDefault()) // get the first order for every customer
.Where(o => o.OrderDate > date) // restrict to the given date
.GroupBy(o => new { o.OrderDate.Year, o.OrderDate.Month) }) // then group by month
.Select(g => new NewCustomerStatsModel {
Month = g.Key.Month,
Year = g.Key.Year,
Count = g.Count()
})
.OrderBy(g => g.Year)
.ThenBy(g => g.Month)
.ToList();

Linq to find lasted record in group

I want add a new column to find which is lasted record in group.
Can I write subquery in Select() method?
I have try this
var test = DailyPeriods.Where(x => x.BookingDate == "2016/12/30")
.Select(x =>
new
{
PERIOD_GROUP_ID = x.PeriodGroupID,
PERIOD_NAME = x.PeriodName,
New_Column = DailyPeriods
.Where(z => z.BookingDate == "2016/12/30")
.Select(a =>
new
{
PeriodGroupID = a.PeriodGroupID,
period_name = a.PeriodName
}
)
.GroupBy(b => b.period_name)
.Select(g => g.Last().PeriodGroupID)
.Contains(x.PeriodName)
})
But will occur this error
"column not in scope: A:2211708.C(BOOKING_DATE)"
Try this..
var lastRecords = periodList.GroupBy(l => l.PeriodName)
.Select(x => new { PeriodName = x.Key,
PeriodGroupId = x.OrderBy(l => l.PeriodGroupId).Last().PeriodGroupId});
var result = from period in periodList
from lastRec in lastRecords.Where(r => r.PeriodGroupId == period.PeriodGroupId
&& r.PeriodName == period.PeriodName)
.DefaultIfEmpty()
select new { period.PeriodGroupId,period.PeriodName, New_Column=lastRec==null?false:true };

Order by Total Value on LinQ

I want to order my Linq GroupBy statement but the item that has the more Total Descending but i can't make it
This is my LinQ
foreach (var item in db
.Pos.Where(r => r.Fecha.Day <= today.Day)
.Select(g => new { Pdv = g.Pdv, Total = g.Total })
.GroupBy(l => l.Pdv)
.AsEnumerable()
.Select(z => new {
Punto_De_Venta=z.Key,
Total = String.Format("{0:$#,##0.00;($#,##0.00);Zero}",
Decimal.Round(z.Sum(l => l.Total), 0))
}))
{
listadepuntos.Add(item.ToString());
}
var grupoPdv = new SelectList(listadepuntos.ToList());
ViewBag.GroupS = grupoPdv;
The Out put of my Linq Statement is :
Punto_De_Venta = Central, Total = 42,143.00
Punto_De_Venta = Restaurante, Total = 189,949.00
Punto_De_Venta = Venta Moto, Total = 89,678.00
And the Output im looking for is:
Punto_De_Venta = Restaurante, Total = 189,949.00
Punto_De_Venta = Venta Moto, Total = 89,678.00
Punto_De_Venta = Central, Total = 42,143.00
How can i do this?? i cant find a way to make this
The List<> does guarantee ordering, sort the List before passing to your SelectList
var grupoPdv = new SelectList(listadepuntos.OrderByDescending(l=>l.Total).ToList());
ViewBag.GroupS = grupoPdv;
Another approach :
Modify source query to return a sorted list.
var results = db.Pos.Where(r => r.Fecha.Day <= today.Day)
.Select(g => new { Pdv = g.Pdv, Total = g.Total })
.GroupBy(l => l.Pdv).AsEnumerable()
.Select(z => new { Punto_De_Venta=z.Key, Total = String.Format("{0:$#,##0.00;($#,##0.00);Zero}", Decimal.Round(z.Sum(l => Total), 0))})
.OrderByDescending(l=>l.Total)
.ToList();
Once you get the sorted list you can create your SelectList with sorted result.
var grupoPdv = new SelectList(result);
ViewBag.GroupS = grupoPdv;
You'll need to do something like this:
foreach (var item in db.Pos.Where(r => r.Fecha.Day <= today.Day)
.Select(g => new { Pdv = g.Pdv, Total = g.Total })
.GroupBy(l => l.Pdv)
.AsEnumerable()
.Select(z => new { Punto_De_Venta = z.Key, Total = z.Sum(l => l.Total) })
.OrderByDescending(r => r.Total)
.Select(r => new { Punto_De_Venta = r.Punto_De_Venta, Total = String.Format("{0:$#,##0.00;($#,##0.00);Zero}", Decimal.Round(z.Sum(l => l.Total), 0))})
{
listadepuntos.Add(item.ToString());
}

C# Linq nested GroupBy and Sum

I'm trying to translate a query I've written to Linq for the past few days I can't seem to make it work. This is the query I'm trying to translate:
SELECT
hsd.CoveragePeriodBeginDate,
RateTotal = SUM(hsd.Rate),
ReimbursementTotal = SUM(hsd.TotalReimbursement),
AdjustmentsTotal = SUM(hsd.Adjustments)
FROM
( SELECT
CoveragePeriodBeginDate,
PaidDate,
Rate = TotalClaimCharge,
TotalReimbursement = ReimbursementAmount,
Adjustments = SUM(BaseRateChangeAmount)
FROM
dbo.HsdMonthlyCapitatation
WHERE
MemberID = 12345678
GROUP BY
CoveragePeriodBeginDate,
PaidDate,
TotalClaimCharge,
ReimbursementAmount
) hsd
GROUP BY
hsd.CoveragePeriodBeginDate
ORDER BY
hsd.CoveragePeriodBeginDate
What I need to do is translate this into Linq. I have tried many different ways, but can't seem to make it work right. It always seems to aggregate too much.
Here's the closest I've come.
var rawCapData = db.HsdMonthlyCapitations.Where(x => x.MemberID == memberID)
.Select(x => new {
CoveragePeriod = x.CoveragePeriodBeginDate,
TotalCharge = x.TotalClaimCharge,
Reimbursement = x.ReimbursementAmount,
PaidDate = x.PaidDate,
Adjust = x.BaseRateChangeAmount
})
.GroupBy(x => new {
CoverageDate = x.CoveragePeriod,
Paid = x.PaidDate,
Rate = x.TotalCharge,
Reimburse = x.Reimbursement
})
.GroupBy(x => new {
Coverage = x.Key.CoverageDate,
DhsRate = x.Sum(y => y.TotalCharge),
ReimbursementTotal = x.Sum(y => y.Reimbursement),
Adjustments = x.Sum(y => y.Adjust)
})
.Select(x => new {
CapMonthYear = x.Key.Coverage,
DhsRate = x.Key.DhsRate,
TotalReimbursement = x.Key.ReimbursementTotal,
AdjustmentsTotal = x.Key.Adjustments
});
I should say I have gotten it to work, but I feel it's rather cludgey and a mix of regular LINQ and lambda expressions, and I would prefer to code it all with lambda expressions, if at all possible. Here's the code I have gotten to work:
var rawCapitationData = from capitation
in db.HsdMonthlyCapitations
where capitation.MemberID == memberID
group capitation by new
{
capitation.CoveragePeriodBeginDate,
capitation.TotalClaimCharge,
capitation.ReimbursementAmount,
capitation.PaidDate
} into cap
select new {
CapitationMonthYear = cap.Key.CoveragePeriodBeginDate,
TotalReimbursement = cap.Key.TotalClaimCharge,
DhsCapitationAmount = cap.Key.ReimbursementAmount,
PaidDate = cap.Key.PaidDate,
DhsAdjustments = cap.Sum(x => x.BaseRateChangeAmount)
};
var capitationData = rawCapitationData.GroupBy(cap => cap.CapitationMonthYear)
.Select(data => new {
CapitationDate = data.Key,
TotalReimbursement = data.Sum(x => x.TotalReimbursement),
DhsCapitationAmount = data.Sum(x => x.DhsCapitationAmount),
DhsAdjustments = data.Sum(x => x.DhsAdjustments)
});
My preference is to do this all in one statement. Is it even possible? I feel I'm close with the lambda expressions, but I know I'm missing something.
Any help or advice is greatly appreciated.
Not sure what are you trying to achieve, but I've ended up with this:
return db.HsdMonthlyCapitations
.Where(x => x.MemberID == memberID)
.GroupBy(x => new {x.CoveragePeriodBeginDate, x.PaidDate, x.TotalClaimCharge, x.ReimbursementAmount})
.Select(x => new
{
x.Key.CoveragePeriodBeginDate,
x.Key.PaidDate,
Rate = x.Key.TotalClaimCharge,
TotalReimbursement = x.Key.ReimbursementAmount,
Adjustments = x.Sum(m => m.BaseRateChangeAmount)
})
.GroupBy(x => x.CoveragePeriodBeginDate)
.Select(x => new
{
CoveragePeriodBeginDate = x.Key,
RateTotal = x.Sum(m => m.Rate),
ReimbursementTotal = x.Sum(m => m.TotalReimbursement),
AdjustmentsTotal = x.Sum(m => m.Adjustments),
})
.OrderBy(x => x.CoveragePeriodBeginDate);

Categories

Resources