0

開始日/終了日を含むオブジェクトのリストがあります。現在のレコードが存在する場合は現在のレコードを見つけようとしていますが、それが失敗した場合は、最近期限切れになったレコードを見つけようとしています。

  • Current は、過去の null 以外の開始日と、null の終了日 (オープン エンド) または将来の終了日として定義されます。
  • 最近期限切れになったものは、最大終了日を持つ現在の期間がないものとして定義できます。理論的には、各オブジェクトによって示される期間が重複することは決してないため、最近期限切れになったものには最大終了日で十分であると予想されます。

私は同様の質問に対するこの回答をたどろうとしていましたが、リストに将来の日付の他のエントリがある場合(つまり、両方が将来の開始日/終了日を持つ場合)、正しいエントリを見つけることができないようです)。

私の試みは次のとおりです。ここで、a は開始日、b は終了日、c はデバッグ中に使用するインジケーター、d はリスト エントリ タイプの定義に使用されます。私はタイプ2にしか興味がありません。

   [TestMethod]
    public void TestRetrievalOfListElements()
    {

        var baseDate = DateTime.Now;

        var list = new[]
        {
             new { a = new DateTime?(baseDate.AddDays(-90)), 
                   b = new DateTime?(baseDate.AddDays(-60)), c = "LongExpired", d=1 },
             new { a = new DateTime?(baseDate.AddDays(-190)), 
                   b = new DateTime?(baseDate.AddDays(-160)), c = "LongestExpired", d=1 },
             new { a = new DateTime?(baseDate.AddDays(-59)), 
                   b = new DateTime?(baseDate.AddDays(+20)), c = "Current", d=1 },
             new { a = new DateTime?(baseDate.AddDays(-159)), 
                   b = new DateTime?(baseDate.AddDays(-91)), c = "LongerExpired", d=1 },
             new { a = new DateTime?(baseDate.AddDays(-90)), 
                   b = new DateTime?(baseDate.AddDays(-60)), c = "LongExpired", d=2 },
             new { a = new DateTime?(baseDate.AddDays(-190)), 
                   b = new DateTime?(baseDate.AddDays(-160)), c = "LongestExpired", d=2 },
             new { a = new DateTime?(baseDate.AddDays(-59)), 
                   b = new DateTime?(baseDate.AddDays(+20)), c = "Current", d=2 },
             new { a = new DateTime?(baseDate.AddDays(-159)), 
                   b = new DateTime?(baseDate.AddDays(-91)), c = "LongerExpired", d=2 },
             new { a = new DateTime?(baseDate.AddDays(+21)), 
                   b = new DateTime?(baseDate.AddDays(+60)), c = "Future", d=2 },

        }.ToList();

        // The following isn't really right either as it doesn't take into account
        // whether d is of type 1 or 2 either. Not sure how to combine aggregates and
        // other conditions ie MIN and of type 2

        var oldestEntry = (from x in list
                          where x.a == list.Min(d => d.a) &&
                          x.d == 2
                          select x).FirstOrDefault();

        Assert.IsTrue(oldestEntry.a == baseDate.AddDays(-190), "Expected oldest date to be 190 days earlier than today");

        var latestEntryThatIsntInTheFuture = 
                          (from x in list
                          from y in list.Where(z => z.d == 2 && z.a <= baseDate)
                          where x.a == list.Max(d => d.a) &&
                          x.d == 2
                          select x).FirstOrDefault();

        Assert.IsTrue(latestEntryThatIsntInTheFuture.a == baseDate.AddDays(-59), "Expected latest date that isn't in the future to be 59 days earlier than today");



    }
4

1 に答える 1

1

これはあなたが探しているものかもしれません:

// Find the current which is defined as a non null start date that is in the past 
// and either a null end date (open ended) or and end date in the future. 
var now = DateTime.Now;
var current = list
    .Where(x => x.a.HasValue && x.a.Value < now && (!x.b.HasValue || x.b.Value > now))
    .FirstOrDefault();
if (current == null)
{ 
    //Then find most recently expired 
    current = list.Where(x => x.b.HasValue)
                  .OrderByDescending(x => x.b)
                  .FirstOrDefault();
}

したがって、私の意見では、クエリに集計は必要ありません。

于 2012-07-12T07:53:03.853 に答える