我使用MVC 5 / EF 6.我一直在尝试创建一个显示多人日历的视图.
我已经按人员分组了视图,并显示了搜索范围内所有日期的列表.但是,如果该人没有安排该日期,则该日期不会列在该人员的下方.
现在,没有人安排任何事情的空日期被归为“空”人组.
我目前的结果:
Person:
-------------------------------
04/01/16 (blank)
04/02/16 (blank)
04/03/16 (blank)
Person: Jane
-------------------------------
04/04/2016: To Do Item
04/05/2016: To Do Item
Person: John
-------------------------------
04/04/2016: To Do Item
04/05/2016: To Do Item
我怎样才能得到这个结果?
Person: Jane
-------------------------------
04/01/16 (blank)
04/02/16 (blank)
04/03/16 (blank)
04/04/2016: To Do Item
04/05/2016: To Do Item
Person: John
-------------------------------
04/01/16 (blank)
04/02/16 (blank)
04/03/16 (blank)
04/04/2016: To Do Item
04/05/2016: To Do Item
查询返回查看
var activecal = db.Calendar.Where(x => (x.CalDate >= startdate && x.CalDate <= enddate).ToList();
// merge calendar with date range in search selected
var calendar = (from d in dateRange //dateRange = date range search
join c in activecal.ToList() on d equals c.CalDate into joinedResult
from r in joinedResult.DefaultIfEmpty()
select new CalVM
{
FullName = r == null ? null : r.FullName,
CalLocation = r == null ? null : r.CalLocation,
calDay = d.Date,
}).ToList();
视图
@{
foreach (var group in Model.GroupBy(a => a.FullName))
{
<h3>Person: @group.Key</h3>
<div class="table-responsive">
<table class="table table-hover small">
<tr>
<th>
Cal Day
</th>
<th>
Location
</th>
</tr>
@foreach (var i in group)
{
<tr>
<td>
@Html.DisplayFor(modelItem => i.calDay)
</td>
<td>
@Html.DisplayFor(modelItem => i.CalLocation)
</td>
</tr>
}
</table>
</div>
}
}
我知道我必须以某种方式获得与dateRange列表中所有日期相关联的人名,我只是不知道该怎么做.日期范围列表中唯一的参数是日期,因此无需加入任何内容.
最佳答案 您可以对该人进行GroupBy,然后对于该范围的每个日期,您将保留该日期的日期和预定事件(我将其命名为ToDo).而且我猜你每个日期可以有多个ToDo.
例:
var dateRange = GetDateRange(new DateTime(2016, 1, 1), new DateTime(2016, 1, 5)).ToList();
var todos = new List<ToDo>
{
new ToDo { Date = new DateTime(2016,1,3), Person = "John", What = "Do that"},
new ToDo { Date = new DateTime(2016,1,4), Person = "John", What = "Do this"},
new ToDo { Date = new DateTime(2016,1,4), Person = "John", What = "Do nothing"},
new ToDo { Date = new DateTime(2016,1,2), Person = "Jane",What = "Do something"},
new ToDo { Date = new DateTime(2016,1,3), Person = "Jane", What = "Do whatever"}
};
var personToDos = todos.GroupBy(x => x.Person)
.ToDictionary(key => key.Key, value => dateRange.Select(date => new ToDosPerDate
{
Date = date,
ToDos = value.Where(a => a.Date == date)
}));
foreach (var item in personToDos)
{
Console.WriteLine(item.Key);
Console.WriteLine("---------------");
foreach (var model in item.Value)
{
Console.Write(model.Date + " ");
Console.WriteLine(string.Join(", ", model.ToDos));
}
Console.WriteLine();
}
还有其他的东西:
public class ToDo
{
public DateTime Date { get; set; }
public string Person { get; set; }
public string What { get; set; }
public override string ToString()
{
return What;
}
}
public class ToDosPerDate
{
public DateTime Date { get; set; }
public IEnumerable<ToDo> ToDos { get; set; }
}
// From: https://stackoverflow.com/questions/3738748/create-an-array-or-list-of-all-dates-between-two-dates
public static IEnumerable<DateTime> GetDateRange(DateTime startDate, DateTime endDate)
{
if (endDate < startDate)
throw new ArgumentException("endDate must be greater than or equal to startDate");
while (startDate <= endDate)
{
yield return startDate;
startDate = startDate.AddDays(1);
}
}
上面代码的输出是:
John
---------------
2016-01-01 12:00:00 AM
2016-01-02 12:00:00 AM
2016-01-03 12:00:00 AM Do that
2016-01-04 12:00:00 AM Do this, Do nothing
2016-01-05 12:00:00 AM
Jane
---------------
2016-01-01 12:00:00 AM
2016-01-02 12:00:00 AM Do something
2016-01-03 12:00:00 AM Do whatever
2016-01-04 12:00:00 AM
2016-01-05 12:00:00 AM
在MVC Razor视图中输出personToDos的示例:
@model Dictionary<string, IEnumerable<ToDosPerDate>>
...
@foreach (var person in Model)
{
<h3>@person.Key</h3>
foreach (var d in person.Value)
{
<div>Date: @d.Date</div>
foreach (var todo in d.ToDos)
{
<div>@todo.What</div>
}
}
}