我正在尝试根据网站管理信息中心的日期字段的一部分创建明细(来自时间间隔分析图表)。
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");
}
}
当然,大日期范围的表现非常糟糕。我希望避免“ToList()”调用,以便在数据库而不是内存中执行向下钻取标准。这就是我被困住的地方,特别是在深入了解每小时和工作日的标准时。
IntervalSelector还用于对图形查询和向下钻取进行分组。我愿意使用单独的选择器来进行深入研究,无论什么都能提高它的性能。图形查询也执行ToList,但性能很好,因为它不需要包含。
var graphQuery = DataManager.DataSessions
.Where(session =>
session.Timestamp >= Model.FromDate &&
session.Timestamp < through);
我想更好的方法是将switch语句移到Linq之外,如下所示:
switch (Model.SelectedInterval)
{
case TimeInterval.Hourly:
int selectedHour = int.Parse(Model.DrillDown);
drilldownQuery = drilldownQuery
.Where(session => session.Timestamp.Hour == selectedHour);
// thoughts on this? any better way?
break;
case TimeInterval.Weekday:
var selectedWeekday = int.Parse(Model.DrillDown) + 1;
// convert to sql dayofweek (Sun = 1)
drilldownQuery =
drilldownQuery.Where(
session => SqlFunctions
.DatePart("weekday", session.Timestamp) ==
selectedWeekday);
// get a NotSupportedException here.
// This function can only be invoked from Linq to Entities
break;
case TimeInterval.Weekly:
case TimeInterval.Monthly:
case TimeInterval.Annual:
default:
// handle these by adjusting the from & through dates?
}
答案 0 :(得分:3)
我刚刚解决了这个问题。在这里,它适用于任何需要它的人:
if (!String.IsNullOrWhiteSpace(model.DrillDown))
{
switch (model.SelectedInterval)
{
case TimeInterval.Weekly:
model.FromDate = DateTime.ParseExact(model.DrillDown,"yyyy/MM/dd",CultureInfo.InvariantCulture);
model.ThroughDate = model.FromDate.AddDays(6);
break;
case TimeInterval.Monthly:
model.FromDate = DateTime.ParseExact(model.DrillDown+"/01", "yyyy/MM/dd", CultureInfo.InvariantCulture);
model.ThroughDate = model.FromDate.AddMonths(1).AddDays(-1);
break;
case TimeInterval.Annual:
model.FromDate = DateTime.ParseExact(model.DrillDown + "/01/01", "yyyy/MM/dd", CultureInfo.InvariantCulture);
model.ThroughDate = model.FromDate.AddYears(1).AddDays(-1);
break;
case TimeInterval.Daily:
model.FromDate = DateTime.ParseExact(model.DrillDown, "yyyy/MM/dd", CultureInfo.InvariantCulture);
model.ThroughDate = model.FromDate;
break;
}
}
var through = model.ThroughDate.AddDays(1);
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))
{
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 = (DayOfWeek) int.Parse(model.DrillDown);
drilldownQuery =
drilldownQuery.Where(
session => session.Timestamp.DayOfWeek == selectedWeekday);
break;
}
}
return drilldownQuery;
}