0

IEnumerable<T>日付であるCreatedフィールドを持つがあります。日付ごと
に複数のが存在する可能性があり、特定の日付にが存在しない場合もあります。TT

現在、これらを日付でグループ化しています。これにより、少なくとも1つの日付Tと、Tその下にあるすべての日付が表示されます。

しかし、私が欲しいのは、指定された日付のが存在するかどうかに関係なく、範囲内のすべての日付を取得するクエリの一部として使用できるものですT

現在のコード:

var adjustments = DAL.GetAdjustmentsInDateRange(Start, End);

from adjustment in adjustments
group adjustment by adjustment.Created.Date into adjustmentsByDay
orderby adjustmentsByDay.Key descending
select ....

ここでは、adjustmentsByDayの間のすべての日付があるわけではありません。私が欲しいのは、要素なしでそれらを含めることです。StartEnd

どうやってやるの?

4

2 に答える 2

2

次のように、グループ化する前にすべての日付のリストを結合調整に残すことができます。

var adjustments = DAL.GetAdjustmentsInDateRange(Start, End);
// Get all unique dates in time span
IEnumerable<DateTime> dates = GetAllDates(Start, End); 

var query = (from date in dates
                join adjustment in adjustments
                    on date.Date equals adjustment.Created.Date into a
                from adjustment in a.DefaultIfEmpty()
                select new {date.Date, adjustment}
                ).GroupBy(i=>i.Date).OrderBy(g=>g.Key);
于 2013-01-17T10:19:28.000 に答える
1

不足しているものをシーケンスに挿入するために、汎用のLINQ-to-objects拡張メソッドをまとめました。

public static IEnumerable<T> InsertMissing<T, U>(this IEnumerable<T> source,
    Func<T, U> key, Func<U, U> increment, Func<U, T> create)
{
    bool first = true;
    U last = default(U);

    foreach (var ig in source)
    {
        U current = key(ig);

        if (first)
        {
            first = false;
            last = current;
            yield return ig;
            continue;
        }

        while (!(last = increment(last)).Equals(current))
        {
            yield return create(last);
        }

        yield return ig;
    }
}

また、次のカスタム実装も必要ですIGrouping

class EmptyGrouping<K, E> : IGrouping<K, E> {
    public K Key { get; set; }

    public IEnumerator<E> GetEnumerator() {
        return Enumerable.Empty<E>().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return this.GetEnumerator(); 
    }
}

次に、の後にクエリを終了しorderby、この呼び出しを続けて、その後に入力する必要がありますselect

var allGroups = query.InsertMissing(
    // Key selector
    g => g.Key,
    // Get next desired key from current key
    d => d.AddDays(-1),
    // Create item for missing key
    d => new EmptyGrouping<DateTime,YourAdjustmentType>{ Key = d });

キーが注文されていない場合、またはキーの1つが正しい場所にない場合(たとえば、真夜中にない場合)、これは問題になります。

これには、キーのリストを生成するために最小/最大値を決定するために元のソースで複数のクエリを実行する必要がなく、データを結合して取得するためにさらにクエリを実行する必要がないという利点があります。

于 2013-01-17T11:06:19.937 に答える