patterncsharpMinor
Returning a list of income for a month
Viewed 0 times
incomereturningformonthlist
Problem
My current code takes 2.7-4.5 seconds to complete, is there any way to make it faster?
I need to return a list of the income in all days in a month. My idea was to loop through the days of one month, but this takes so long should not be a hard task.
What can I improve? I was thinking on
```
public IEnumerable GetSellInvoices(int month, int year, int offset)
{
DateTime startDate = new DateTime(year, month, 1, 0, 0, 0).AddMinutes(offset);
DateTime endDate = new DateTime(year, month, DateTime.DaysInMonth(year, month) , 23, 59, 59, 999).AddMinutes(offset);
DateTime utc = DateTime.UtcNow.AddMinutes(-offset);
DateTime maxDate = new DateTime(utc.Year, utc.Month, utc.Day, 23, 59, 59, 999).AddMinutes(offset);
if (endDate > maxDate) endDate = maxDate;
var invoices =
db.SellInvoices.Where(invoice => invoice.Date >= startDate && invoice.Date result = new List();
DateTime counterDate = startDate;
while (counterDate invoice.Date >= iDate && invoice.Date x.CardSettlementSum).DefaultIfEmpty(0).Sum();
decimal cfCash = dayInvoices.Select(x => x.CashSettlementSum).DefaultIfEmpty(0).Sum();
decimal depositsCard = dayInvoices.Select(x => x.CardDepositSum).DefaultIfEmpty(0).Sum();
decimal depositsCash = dayInvoices.Select(x => x.CashDepositSum).DefaultIfEmpty(0).Sum();
decimal notSyledsDecimal = dayInvoices.Select(x => x.NotStyledsSum).DefaultIfEmpty(0).Sum();
decimal discountsDecimal = dayInvoices.Select(x => x.DiscountsSum).DefaultIfEmpty(0).Sum();
result.Add(new GetSellInfo
{
Date = counterDate,
TotalCard = cfCard + depositsCard,
TotalCash = cfCash + depositsCash,
DepositsInCard = depositsCard,
DepositsInCash = depositsCash,
NotStyleds = notSyledsDecimal,
Discounts = discountsDecimal,
Returns = cfCard - depositsCard + cfCash + depositsCash,
Total = c
I need to return a list of the income in all days in a month. My idea was to loop through the days of one month, but this takes so long should not be a hard task.
What can I improve? I was thinking on
GroupBy a date range.```
public IEnumerable GetSellInvoices(int month, int year, int offset)
{
DateTime startDate = new DateTime(year, month, 1, 0, 0, 0).AddMinutes(offset);
DateTime endDate = new DateTime(year, month, DateTime.DaysInMonth(year, month) , 23, 59, 59, 999).AddMinutes(offset);
DateTime utc = DateTime.UtcNow.AddMinutes(-offset);
DateTime maxDate = new DateTime(utc.Year, utc.Month, utc.Day, 23, 59, 59, 999).AddMinutes(offset);
if (endDate > maxDate) endDate = maxDate;
var invoices =
db.SellInvoices.Where(invoice => invoice.Date >= startDate && invoice.Date result = new List();
DateTime counterDate = startDate;
while (counterDate invoice.Date >= iDate && invoice.Date x.CardSettlementSum).DefaultIfEmpty(0).Sum();
decimal cfCash = dayInvoices.Select(x => x.CashSettlementSum).DefaultIfEmpty(0).Sum();
decimal depositsCard = dayInvoices.Select(x => x.CardDepositSum).DefaultIfEmpty(0).Sum();
decimal depositsCash = dayInvoices.Select(x => x.CashDepositSum).DefaultIfEmpty(0).Sum();
decimal notSyledsDecimal = dayInvoices.Select(x => x.NotStyledsSum).DefaultIfEmpty(0).Sum();
decimal discountsDecimal = dayInvoices.Select(x => x.DiscountsSum).DefaultIfEmpty(0).Sum();
result.Add(new GetSellInfo
{
Date = counterDate,
TotalCard = cfCard + depositsCard,
TotalCash = cfCash + depositsCash,
DepositsInCard = depositsCard,
DepositsInCash = depositsCash,
NotStyleds = notSyledsDecimal,
Discounts = discountsDecimal,
Returns = cfCard - depositsCard + cfCash + depositsCash,
Total = c
Solution
I'm going to elaborate on what I mentioned in comments.
Assuming you're using LINQ to Entities, this line:
does not actually execute the query. It just builds the query, execution is deferred until you call one of the methods that force the materialization of the result set. One of those methods is
That means you're calling the database 6 times per loop.
If you add
You'll just hit the database once, grab the full result set and the rest of the processing will be done in-memory.
In case of not-too-big datasets, that is definitely a viable way to go. Otherwise, you'd have to write a stored procedure to do the processing.
Assuming you're using LINQ to Entities, this line:
var invoices =
db.SellInvoices
.Where(invoice => invoice.Date >= startDate && invoice.Date <= endDate);does not actually execute the query. It just builds the query, execution is deferred until you call one of the methods that force the materialization of the result set. One of those methods is
Sum.That means you're calling the database 6 times per loop.
If you add
.ToList():var invoices =
db.SellInvoices
.Where(invoice => invoice.Date >= startDate && invoice.Date <= endDate)
.ToList();You'll just hit the database once, grab the full result set and the rest of the processing will be done in-memory.
In case of not-too-big datasets, that is definitely a viable way to go. Otherwise, you'd have to write a stored procedure to do the processing.
Code Snippets
var invoices =
db.SellInvoices
.Where(invoice => invoice.Date >= startDate && invoice.Date <= endDate);var invoices =
db.SellInvoices
.Where(invoice => invoice.Date >= startDate && invoice.Date <= endDate)
.ToList();Context
StackExchange Code Review Q#63189, answer score: 6
Revisions (0)
No revisions yet.