I am trying to create a scan based on part of a date field for the admin site control panel (from the interval analysis diagram).


var drilldownQuery = DataManager.DataSessions
.Include("Location")
.Include("Quote.Carriers")
.Include("Drivers")
.Include("Vehicles")
.Where(session =>
session.Timestamp >= Model.FromDate &&
session.Timestamp < through
);
if (!String.IsNullOrWhiteSpace(Model.DrillDown))
{
drilldownQuery = drilldownQuery.ToList()
.Where(session =>
IntervalSelector(session) == Model.DrillDown);
}
public string IntervalSelector(DataSession session)
{
switch (Model.SelectedInterval)
{
case TimeInterval.Hourly:
return session.Timestamp.Hour.ToString("D2");
case TimeInterval.Weekday:
return ((int)session.Timestamp.DayOfWeek).ToString();
case TimeInterval.Weekly:
return session.Timestamp.Date.AddDays(-(int)session.Timestamp.DayOfWeek).ToString("yyyy/MM/dd");
case TimeInterval.Monthly:
return session.Timestamp.Date.ToString("yyyy/MM");
case TimeInterval.Annual:
return session.Timestamp.Year.ToString("D4");
default:
return session.Timestamp.Date.ToString("yyyy/MM/dd");
}
}
Of course, this is very bad with large date ranges. I hope to avoid calling "ToList ()" so that the drilling criteria runs in the database, not in memory. And this is the place where I got stuck, especially when drilling by hourly and everyday criteria.
IntervalSelector is also used to group graph requests, as well as for drilling. I am open to using a separate selector for granularity, which will improve its performance. In the graph request, a ToList is also executed, but the performance is excellent because it does not need to be included.
var graphQuery = DataManager.DataSessions
.Where(session =>
session.Timestamp >= Model.FromDate &&
session.Timestamp < through);
I assume the best route would be to move the switch statement outside of Linq, for example:
switch (Model.SelectedInterval)
{
case TimeInterval.Hourly:
int selectedHour = int.Parse(Model.DrillDown);
drilldownQuery = drilldownQuery
.Where(session => session.Timestamp.Hour == selectedHour);
break;
case TimeInterval.Weekday:
var selectedWeekday = int.Parse(Model.DrillDown) + 1;
drilldownQuery =
drilldownQuery.Where(
session => SqlFunctions
.DatePart("weekday", session.Timestamp) ==
selectedWeekday);
break;
case TimeInterval.Weekly:
case TimeInterval.Monthly:
case TimeInterval.Annual:
default:
}