我使用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,5)).ToList(); var todos = new List<Todo> { new Todo { Date = new DateTime(2016,3),Person = "John",What = "Do that"},new Todo { Date = new DateTime(2016,4),What = "Do this"},What = "Do nothing"},2),Person = "Jane",What = "Do something"},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> } } }