我正在尝试在不同设备上获取过去30天内我的应用的总下载次数,我成功返回正确的查询,按天数分组并加入过去30天的可枚举。但是我无法按照自己的意愿格式化输出。让我先与LinqPad中的演示文稿分享查询
var last_days = (from idx in Enumerable.Range(1, (DateTime.Now - DateTime.Now.AddDays(-30)).Days)
select new { day = DateTime.Now.AddDays(-30).AddDays(idx).Date});
var orders = (from od in Orders
group od by EntityFunctions.AddSeconds((DateTime?)new DateTime(1970,1,1,0,0,0,0), (int?)od.Created) into g
select new {
day = g.Key ,
web = g.Where( q => q.Source == "web").Count(),
ios = g.Where( q => q.Source == "ios").Count(),
android = g.Where( q => q.Source == "android").Count(),
total = g.Count()
}).OrderByDescending(q => q.day).Take(31);
var days=
(from d in last_days
join od in orders on d.day equals od.day into x
from od in x.DefaultIfEmpty()
select x );
days.Dump();
这是我得到的结果
现在,我想将最终输出格式化为IEnumerable 5列(day,web,ios,android,total),无论它是否为空。所以我没有空O标志,而是获得日期,而web = ios = android = total = 0.我怎么能这样做? 因此,在没有任何下载的日子里,我仍然可以获得日期和平台为0的条目。
答案 0 :(得分:2)
这不是最优雅的解决方案,但这样的事情应该有效:
var days = last_days.Select(d =>
orders.DefaultIfEmpty(new {
day = d,
web = 0,
ios = 0,
android = 0,
total = 0
}).FirstOrDefault(od =>
od.day == d.Date));
基本的想法是告诉发电机在每种情况下,如果找不到合适的订单条目,应该依靠什么。
回想起来,从空白的石板开始可能更容易。更像是什么:
var last_30_days =
from idx in Enumerable.Range(1, 30)
orderby idx descending
select DateTime.Now.AddDays(idx - 30).Date;
var orders =
from date in last_30_days
let datesOrders = Orders.Where(order => order.Created == date)
select new Info()
{
Date = date,
Web = datesOrders.Where(q => q.Source == "web").Count(),
iOS = datesOrders.Where(q => q.Source == "ios").Count(),
Android = datesOrders.Where(q => q.Source == "android").Count(),
Total = datesOrders.Count()
};
答案 1 :(得分:0)
如何选择新的DaySum {ord =(ord == null?0:ord.Count)};
而不仅仅是
选择x
答案 2 :(得分:0)
说得对,生成的sql在复杂性方面没问题,在linq上有点生疏我猜
var last_days = (from idx in Enumerable.Range(1, (DateTime.Now - DateTime.Now.AddDays(-31)).Days)
select new { day = DateTime.Now.AddDays(-31).AddDays(idx).Date});
var orders = (from od in Orders
where od.ServiceProviderID == 2
group od by new DateTime(1970,1,1,0,0,0,0).AddSeconds(od.Created).Date into g
select new {
day = (DateTime)g.Key ,
web = g.Where( q => q.Source == "web").Count(),
ios = g.Where( q => q.Source == "ios").Count(),
android = g.Where( q => q.Source == "android").Count(),
total = g.Count()
}).OrderByDescending(q => q.day).Take(32);
var days = (from d in last_days
join od in orders on d.day.Date equals od.day.Date into x
from od in x.DefaultIfEmpty()
select new {
day = d.day ,
web = (od == null) ? 0: od.web,
ios = (od == null) ? 0: od.ios,
android = (od == null) ? 0: od.android,
total = (od == null) ? 0 : od.total
} );
days.Dump();