格式化报告的GroupBy结果

时间:2014-09-02 22:10:05

标签: c# performance linq knockout.js

我几天都在苦苦挣扎。我创建了一份报告来衡量员工对客户的访问(a.k.a.访问KPI)。

该报告实际上正在运行,但加载时间大约为10秒,我已设法使用GroupBy语句解决这个问题,而不是定期创建列表,查询,查询,另一组列表和序列化为JSON。

我需要做的是非常简单"。我查询某一年的某个月(例如:2014年8月),但我需要在此之前的2个月内检索信息,使用该示例,我需要2014年8月,2014年7月和2014年6月的数据。列显示八月的信息,七月的信息,依此类推。使用GroupBy我设法得到这个,所以结果是这样的:

  1. 用户1
    • 八月
      • 报道访问量:3
      • UnReported Visits:2
    • 七月
      • 报道访问量:5
      • UnReported Visits:3
    • 六月
      • 报道的访问次数:1
      • UnReported Visits:6
  2. 用户2
    • 八月
      • 报道访问量:3
      • UnReported Visits:2
    • 六月
      • 报道的访问次数:1
      • UnReported Visits:6
  3. 等等......

    嗯,我在这里可以,但我需要总是检索3个时间段,例如用户2没有7月的信息,因为他当月没有进行任何访问。问题是我需要JULY列的结果全部为零以适合我的表/列布局(在HTML中)。像这样:

    1. 用户1
      • 八月
        • 报道访问量:3
        • UnReported Visits:2
      • 七月
        • 报道访问量:5
        • UnReported Visits:3
      • 六月
        • 报道的访问次数:1
        • UnReported Visits:6
    2. 用户2
      • 八月
        • 报道访问量:3
        • UnReported Visits:2
      • 七月
        • 报告的访问次数:0
        • UnReported Visits:0
      • 六月
        • 报道的访问次数:1
        • UnReported Visits:6
    3. LINQ声明我正在使用:

      var visitasGrouped = from visit in visits
                           group visit by visit.Author into visitsAuthor
                           orderby visitsAuthor.Key ascending
                           from visitsGroup in
                               (from visit in visitsAuthor
                                group visit by visit.DateScheduled.Month)
                           group visitsGroup by visitsAuthor.Key;
      

      显然,count()部分是在foreach语句中计算的。

      任何帮助都会受到赞赏,包括改进LINQ语句,任何C#/ LINQ法术,使用Knockout或jQuery格式化收到的JSON数组。一切。

      感谢您的回复。

2 个答案:

答案 0 :(得分:0)

在没有编译器或任何测试的情况下执行此操作,但这应该让您走上正确的道路:

var months = Enumerable.Range(0, 2)
    .Select(x => endDate.AddMonths(-1*x).Month))
    .ToList();

var results = visits
    .GroupBy(v => v.Author)
        .SelectMany(v => months
            .Select(m =>
                new {
                    author = v.Key,
                    month = m,
                    reportedVisits = v.Count(v => v.Reported && v.DateScheduled.Month = m),
                    unreportedVisits = v.Count(v => v.Unreported && v.DateScheduled.Month = m),
                });

请注意,如果访问是一个大型数据集,这可能效率低下,而且我不知道这是否会愉快地转换为SQL。就像我说的,我的LINQ并不好。但它告诉你校长:那些月份不会来自任何地方,你需要自己指定它们。

答案 1 :(得分:0)

对于SQL,请加入一组月份,为每个用户提供可预测的基本结果,如另一个答案所示。如果您在获得输出之后转换输出,那么javascript和knockout应该很容易在这里使用:

// assuming your data looks like:
var data = {
    user1: { august: 10, july: 4 },
    user2: { august: 8, june: 3 }
};

// then generate some set of defaults like:
var defaults = { august: 0, july: 0, june: 0 };

// and do this to normalize each user:
Object.getOwnPropertyNames(data).map(function (user) {
    // assuming jquery, but replace with any object copying logic otherwise
    return $.extend({}, defaults, data[user]);
});