c# - Linq DefaultValues on Join -


i'm trying total download count of app last 30 days on different devices, succeeded of returning right query, grouping number of days , joinning enumerable last thirty days. i'm not able format output want. let me share query first presentation in 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 entityfunctions.addseconds((datetime?)new datetime(1970,1,1,0,0,0,0), (int?)od.created) 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 x od in x.defaultifempty() select x );  days.dump(); 

this result get

enter image description here

now, want format final output ienumerable of 5 columns(day, web, ios, android, total) regardless whether empty or not. instead of empty o sign, date, , web = ios = android = total = 0. how can this? on day without downloads, still entry date , platforms 0.

this hardly elegant solution, should work:

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

the basic idea tell generator fall on, in each case, if appropriate order entry cannot found.


in retrospect, it's easier start blank slate. more like:

var last_30_days =   idx in enumerable.range(1, 30)   orderby idx descending   select datetime.now.adddays(idx - 30).date;  var orders =   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()   }; 

Comments