asp.net-mvc – 左加入日期,分组结果,在分组结果中显示所有日期,即使为空

我使用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>
        }
    }
}

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....