从c#中的表创建矩阵

时间:2017-11-14 19:14:02

标签: c# asp.net-mvc linq

使用.Net MVC我正在使用DB First方法。我需要一个学校日计划,但我不确定使用透视,DataTable还是其他任何东西?

SQL中的表是这样的:

WeeklyProgram
Id RoomId Hour Day
1  1      9    1
2  1      12   1
3  2      14   1
4  2      12   2
5  3      11   1
6  4      10   2

尝试将其转换为html中的表格,其中包含以下空单元格:

For Day 1 My School Program is;
#     Room1 Room2 Room3
9:00  1     null  null
10:00 null  null  null
11:00 null  null  5
12:00 2     null  null
13:00 null  null  null
14:00 null  3     null

尝试pivoting,但无法得到我的想法。

谢谢大家。

更新:我发现了答案

if (!date.HasValue)
            date = DateTime.Now;

        List<WeeklyProgram> modelBase = table
            .Where(b => b.Day == day)
            .ToList();

        int[] hours = { 9, 10, 11, 12, 13, 14};

        List<PivotTable> pivotTable = new List<PivotTable>();

        foreach (var hour in hours)
        {
            PivotTable pivotRow = new PivotTable() { Hour = hour };

            foreach (var item in modelBase)
                if (item.Hour == hour)
                    switch (item.RoomId)
                    {
                        case 1:
                            pivotRow.Room1 = item.Id;
                            break;
                        case 2:
                            pivotRow.Room2 = item.Id;
                            break;
                        case 3:
                            pivotRow.Room3 = item.Id;
                            break;
                    }
            pivotTable.Add(pivotRow);
        }

        return pivotTable;

-

    public class PivotTable
{
    public int Hour { get; set; }
    public int Room1 { get; set; }
    public int Room2 { get; set; }
    public int Room3 { get; set; }
    public int Room4 { get; set; }
    public int Room5 { get; set; }
}

1 个答案:

答案 0 :(得分:0)

首先,您需要将WeeklyProgram过滤到感兴趣的日期:

var dayProgram = from c in WeeklyProgram
                 where c.Day == 1
                 select c;

然后,您可以从该数据中提取每小时计划行,通过将Id转换为可以为空的类型为未计划的房间留下空值,然后将其转换为Dictionary以供稍后查找:

var dayClasses = (from c in dayProgram
                  group c by c.Hour into cg
                  let cgd = cg.ToDictionary(c => c.RoomId, c => (int?)c.Id)
                  select new {
                      Hour = cg.Key,
                      Room1 = cgd.GetValueOrDefault(1),
                      Room2 = cgd.GetValueOrDefault(2),
                      Room3 = cgd.GetValueOrDefault(3)
                  }).ToDictionary(c => c.Hour, c => c);

现在您提取WeeklyProgram期间使用的所有小时数:

var hoursInWeek = (from c in WeeklyProgram
                   orderby c.Hour
                   select c.Hour).Distinct();

现在您已准备好将所用时间与预定的房间相结合:

var ans = from h in hoursInWeek
          select new {
              Hour = $"{h}:00",
              Room1 = dayClasses.GetValueOrDefault(h)?.Room1,
              Room2 = dayClasses.GetValueOrDefault(h)?.Room2,
              Room3 = dayClasses.GetValueOrDefault(h)?.Room3
          };

这使用辅助函数来查找字典,其中密钥可能不容易存在(注意:这使用了C#7.1之前的所有功能。)

static public class Ext {
    public static TV GetValueOrDefault<TK, TV>(this IDictionary<TK, TV> dict, TK key, TV defaultValue = default) => dict.TryGetValue(key, out TV value) ? value : defaultValue;
}

对于早期版本的C#,您可以使用此版本:

static public class Ext {
    public static TV GetValueOrDefault<TK, TV>(this IDictionary<TK, TV> dict, TK key, TV defaultValue = default(TV)) => dict.TryGetValue(key, out TV value) ? value : defaultValue;
}