0

我有IEnumerable<T>一个Created字段,即日期。
每个日期可以有多个',有时给定日期T没有'。T

目前我正在按日期对这些进行分组,这给了我所有至少有一个的日期T,并且T在它们下面。

不过,我想要的是我可以将其用作查询的一部分,该查询将使我获得一个范围内的所有日期,而不管T给定日期是否有任何 's。

当前代码:

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 });

如果您的钥匙没有订购或者其中一个钥匙没有放在正确的位置(例如,在您的情况下,不是在午夜),这将变得混乱。

这样做的好处是不需要对原始源进行多次查询来确定最小值/最大值以生成键列表,然后再进行进一步的查询来连接和获取数据。

于 2013-01-17T11:06:19.937 回答