我目前有以下代码来生成过去 30 天内的销售报告。我想知道是否可以使用 linq 一步生成此报告,而不是我这里的相当基本的循环。
对于我的要求,每天都需要返回一个值给我,所以如果任何一天没有销售,则返回 0。
任何 Sum linq 示例都没有解释如何包含 where 过滤器,因此我对如何获取最近几天每天的总金额感到困惑,或者如果没有销售则为 0我路过。
感谢您的帮助, 丰富
//setup date ranges to use
DateTime startDate = DateTime.Now.AddDays(-29);
DateTime endDate = DateTime.Now.AddDays(1);
TimeSpan startTS = new TimeSpan(0, 0, 0);
TimeSpan endTS = new TimeSpan(23, 59, 59);
using (var dc = new DataContext())
{
//get database sales from 29 days ago at midnight to the end of today
var salesForDay = dc.Orders.Where(b => b.OrderDateTime > Convert.ToDateTime(startDate.Date + startTS) && b.OrderDateTime <= Convert.ToDateTime(endDate.Date + endTS));
//loop through each day and sum up the total orders, if none then set to 0
while (startDate != endDate)
{
decimal totalSales = 0m;
DateTime startDay = startDate.Date + startTS;
DateTime endDay = startDate.Date + endTS;
foreach (var sale in salesForDay.Where(b => b.OrderDateTime > startDay && b.OrderDateTime <= endDay))
{
totalSales += (decimal)sale.OrderPrice;
}
Response.Write("From Date: " + startDay + " - To Date: " + endDay + ". Sales: " + String.Format("{0:0.00}", totalSales) + "<br>");
//move to next day
startDate = startDate.AddDays(1);
}
}
编辑: 约翰内斯的回答是处理我的疑问的好方法。下面是对代码的调整,以使其适用于本示例,以防其他人遇到此问题。这将从 allDays 表执行外部联接,并在当天没有销售时返回 0 值。
var query = from d in allDays
join s in salesByDay on d equals s.Day into j
from s in j.DefaultIfEmpty()
select new { Day = d, totalSales = (s != null) ? s.totalSales : 0m };
最佳答案
您可以按天对所有数据进行分组,并对这些组进行求和。为了满足每天求和的要求,即使是没有顺序的,您可以加入所有日期的列表,或者简单地使用循环来确保包含所有日期。小提示:如果通过 DateTime.Date
属性进行比较,则无需显式设置时间。
这是使用生成器函数的解决方案(取自 MoreLinq 项目):
public static partial class MoreEnumerable
{
public static IEnumerable<TResult> GenerateByIndex<TResult>(Func<int, TResult> generator)
{
// Looping over 0...int.MaxValue inclusive is a pain. Simplest is to go exclusive,
// then go again for int.MaxValue.
for (int i = 0; i < int.MaxValue; i++)
{
yield return generator(i);
}
yield return generator(int.MaxValue);
}
}
public class MyClass
{
private void test()
{
DateTime startDate = DateTime.Now.AddDays(-29);
DateTime endDate = DateTime.Now.AddDays(1);
using (var dc = new DataContext())
{
//get database sales from 29 days ago at midnight to the end of today
var salesForPeriod = dc.Orders.Where(b => b.OrderDateTime > startDate.Date && b.OrderDateTime <= endDate.Date);
var allDays = MoreEnumerable.GenerateByIndex(i => startDate.AddDays(i)).Take(30);
var salesByDay = from s in salesForPeriod
group s by s.OrderDateTime.Date into g
select new {Day = g.Key, totalSales = g.Sum(x=>(decimal)x.OrderPrice};
var query = from d in allDays
join s in salesByDay on s.Day equals d
select new {Day = s.Day , totalSales = (s != null) ? s.totalSales : 0m;
foreach (var item in query)
{
Response.Write("Date: " +item.Day.ToString() " Sales: " + String.Format("{0:0.00}", item.totalSales) + "<br>");
}
}
}
}
关于c# - 使用 Linq to SQL 生成销售报告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2844839/