2011-02-09 21 views
2

これは、ループではなくLinqで行うのが良い方法があれば、やってみることができます。これは私が今行っていることです。範囲内のLinqクエリ集計の日付

私の製品が2つの日付の間にアクティブである日数が必要です。

Productには多くのProductHistoriesがあり、ProductHistoryにはDateActiveとDateInactiveの値があります。この履歴が進行中であることを示すために、DateInactiveをnullにすることができます。歴史は重複しません。

startDateまたはProductHistoryのDateActiveの最大値を合計し、endDateまたはProductHistoryのDateInactiveの最小値(DateInactiveに値がない場合は、デフォルトでendDate)の合計からその合計を差し引きます。

は2011-01-01(1月1日)の間で活発な日のアクティブ数を取得し、2011年2月1日(2月1日)

履歴::

Active 2010-12-25 : Inactive 2011-01-05 
Active 2011-01-15 : Inactive 2011-01-20 
Active 2011-01-25 : Inactive null 

は例を働いこれは16日、合計すべきである(4 + 5 + 7)

現時点では私の最高はかなり醜いです:

Dim a As Integer = (From h In histories 
      Select If(h.ActiveDate > startDate, h.ActiveDate, startDate)).Sum(Function(d) d.Ticks)/TimeSpan.TicksPerDay 

    Dim b As Integer = (From h In histories 
      Select If(h.InactiveDate.HasValue AndAlso h.InactiveDate < endDate, h.InactiveDate, endDate)).Sum(Function(d) d.Value.Ticks)/TimeSpan.TicksPerDay 

Return b - a 

どのような考えですか? (C#またはVBのいずれかが上手く、私は翻訳します)

答えて

1

何かこれは何ですか?のみ日付範囲内を開始履歴を考慮

var numDays = product 
      .ProductHistories 
      .Where(ph => ph.Active >= start && ph.Active < end) 
      .Sum(ph => ph.Active 
          .Subtract(end > ph.Inactive ? ph.Inactive.Value : end) 
          .Duration() // because we are doing start - end 
          .Days); 
  1. (重複履歴を負うものではありません)。
  2. 各履歴について、有効期限と無効日時と終了日のより前のの間のデルタとしてタイムパンを構成します。
  3. それらを合計します。

はこれを改善するために、私はお勧め:

  1. はあなたがph.Active.IsBetween(start, end)としてどこラムダを書いてみましょううIsBetween拡張子を書きます。
  2. 合計のラムダを別の方法で抽出し、より直観的に書く。 DateTime?に "持ち上げられた"演算子を使用すると、多くの人が直感的ではないことがわかります。
関連する問題