0

我正在使用 C#、NHibernate、Fluent NHibernate 和 LINQ(存储库模式)。

关于我想做什么的虚构故事

假设我有一个停车位,所以我有一辆车从日期租到日期。这成为数据库的一个条目。

我想知道过去 30 天内每天有多少辆车。所以可以在趋势图中使用的数据。

描述

我所拥有的是数据库中的条目,如下所示:

Entry:
--------
ID
StartDate
EndDate

each day我需要找出一段时间内有多少条目(比如last 30 days)。

如果我在数据库中说这些数据:

ID | Start      | End
---|------------|----------
1  | 2013-01-01 | 2013-01-01
2  | 2013-01-02 | 2013-01-02
3  | 2013-01-02 | 2013-01-03 <-- NOTICE
4  | 2013-01-03 | 2013-01-03
5  | 2013-01-03 | 2013-01-05 <-- NOTICE
6  | 2013-01-04 | 2013-01-05

我有日期范围2013-01-01直到2013-01-05

我除了结果:

Date       | Value | Entry IDs (not part of the result, only here for clarity)
-----------|-------|-----------
2013-01-01 | 1     | 1
2013-01-02 | 2     | 2 3
2013-01-03 | 3     | 3 4 5
2013-01-04 | 2     | 5 6
2013-01-05 | 2     | 5 6

我目前只分组startdate,然后获取数字,但现在这是无效的,因为添加了enddate.

我可以为该范围内的每一天做一个,尝试找到与之匹配的条目,但我认为这在数据库或 Web 服务上过于昂贵。

建议?

4

2 回答 2

1

也许是这样的:

var start = new DateTime(2013, 01, 01);
var end = DateTime(2013, 01, 05);

var q = d.Query()
         .Where(x =>
             x.Date >= start
             && end >= x.Date) // there you filter for range 
         .GroupBy(x => x.Date); // use .Day to group by day

包括开始时间和结束时间。

编辑

我发现了这个(实际上我的项目中有一个类似的案例):

var start = new DateTime(2013, 1, 1);
var end = new DateTime(2013, 1, 5);
var current = start;
var ranges = new List<DateTime>();

while (current <= end)
{
    ranges.Add(current);

    current = current.AddDays(1);
}

var res = ranges.Select(x => new
{
    date = x,
    entries = entries.Where(e => e.Start <= x && x <= e.End).ToList()
}).ToList();

尝试对其进行测试,也许您可​​以适应您的情况(请注意,过滤从日期范围开始)。

于 2013-09-17T10:59:10.237 回答
0

您可以使用.NET 的时间周期库来计算趋势数据:

// ----------------------------------------------------------------------
class CarPeriod : DayTimeRange
{

  // --------------------------------------------------------------------
  public CarPeriod( int id, DateTime start, DateTime end ) :
    this( id, start, end.Date.AddDays( 1 ).Subtract( start.Date ).Days )
  {
  } // CarPeriod

  // --------------------------------------------------------------------
  public CarPeriod( int id, DateTime start, int days ) :
    base( start.Year, start.Month, start.Day, days )
  {
    Id = id;
  } // CarPeriod

  // --------------------------------------------------------------------
  public int Id { get; private set; }

} // class CarPeriod

// ----------------------------------------------------------------------
[Sample( "DaysTrendData" )]
public void DaysTrendData()
{
  // periods
  ITimePeriodCollection carPeriods = new TimePeriodCollection();
  carPeriods.Add( new CarPeriod( 1, new DateTime( 2013, 1, 1 ), new DateTime( 2013, 1, 1 ) ) );
  carPeriods.Add( new CarPeriod( 2, new DateTime( 2013, 1, 2 ), new DateTime( 2013, 1, 2 ) ) );
  carPeriods.Add( new CarPeriod( 3, new DateTime( 2013, 1, 2 ), new DateTime( 2013, 1, 3 ) ) );
  carPeriods.Add( new CarPeriod( 4, new DateTime( 2013, 1, 3 ), new DateTime( 2013, 1, 3 ) ) );
  carPeriods.Add( new CarPeriod( 5, new DateTime( 2013, 1, 3 ), new DateTime( 2013, 1, 5 ) ) );
  carPeriods.Add( new CarPeriod( 6, new DateTime( 2013, 1, 4 ), new DateTime( 2013, 1, 5 ) ) );

  Days testDays = new Days( new DateTime( 2013, 1, 1 ), 5 );
  foreach ( Day testDay in testDays.GetDays() )
  {
    Console.Write( "Day: " + testDay + ": " );
    foreach ( CarPeriod carPeriod in carPeriods )
    {
      if ( carPeriod.IntersectsWith( testDay ) )
      {
        Console.Write( carPeriod.Id + " " );
      }
    }
    Console.WriteLine();
  }
} // DaysTrendData
于 2013-09-17T12:48:51.240 回答