Asp.net core mvc NET内核中的DB视图

Asp.net core mvc NET内核中的DB视图,asp.net-core-mvc,asp.net-core-1.0,Asp.net Core Mvc,Asp.net Core 1.0,我为CRUD设置了一个DB注入的表 ID EID Task entrydate Level 1 1 Demographics 2017-02-23 2 2 0 Demographics 2017-02-23 2 3 1 Progress Notes 2017-03-06 2 4 1 Demographics 2017-03-06 3 5 1 Assessments 2

我为CRUD设置了一个DB注入的表

ID EID      Task         entrydate  Level 
1   1   Demographics    2017-02-23    2 
2   0   Demographics    2017-02-23    2 
3   1   Progress Notes  2017-03-06    2 
4   1   Demographics    2017-03-06    3 
5   1   Assessments     2017-03-06    3 
6   1   Assessments     2017-01-25    1
但是,为了以对客户端有意义的方式显示数据,我需要按entrydate在列中列出级别数据

ID EId      Task         25 Jan 2017    23 Feb 2017 06 Mar 2017
1   1   Demographics        NULL            2          NULL
2   0   Demographics        NULL            2          NULL
3   1   Progress Notes      NULL          NULL          2
4   1   Demographics        NULL          NULL          3
5   1   Assessments         NULL          NULL          3
6   1   Assessments          1            NULL         NULL
我一直致力于在控制器和视图中使用LINQ在视图中创建正确的表

控制器:

public IActionResult Index(int id)
    {
        HttpContext.Session.SetInt32("EmployeeID", id);
        var model = db.EmployeeTask
            .Where(h => h.EmployeeId == id)
            .OrderByDescending(h => h.Entrydate);

        return View(model);
    }
private static List<Dictionary<string, object>> LoadData(string sqlSelect, 
    params object[] sqlParameters)
    {
        var table = new List<Dictionary<string, object>>();
        using (var ctx = new DBContext())
        {
            ctx.Database.GetDbConnection();
            ctx.Database.OpenConnection();
            using (var cmd = ctx.Database.GetDbConnection().CreateCommand())
            {
                cmd.CommandText = sqlSelect;
                foreach (var param in sqlParameters)
                    cmd.Parameters.Add(param);
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var row = new Dictionary<string, object>();
                        for (int i = 0; i < reader.FieldCount; i++)
                            row[reader.GetName(i)] = reader[i];
                        table.Add(row);
                    }

                    if (table == null)
                    {
                        var row = new Dictionary<string, object>();
                        for (int i = 0; i < 1; i++)
                            row[reader.GetName(i)] = "None";
                        table.Add(row);
                    }
                }
            }
        }
        return table;
    }
public IActionResult Index(int id, string datestart, string dateend)
    {
        HttpContext.Session.SetInt32("EmployeeID", id);

        if(datestart == null)
        {
            var setdate = DateTime.Now;
            datestart = setdate.AddMonths(-3).ToString(); 
        }

        if(dateend == null)
        {
            dateend = DateTime.Now.ToString();
        }

        var start = new SqlParameter("@StartDate", datestart);
        var end = new SqlParameter("@EndDate", dateend);
        var EmpId = new SqlParameter("@Id", id);
        var tasks = LoadData("EXECUTE dbo.TaskView @StartDate, @EndDate, 
                    @Id",start,end,EmpId);

        ViewBag.start = DateTime.Parse(datestart);
        ViewBag.end = DateTime.Parse(dateend);
        return View(tasks);
    }
查看页面:

<table class="table">
<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.KeyTask)
        </th>
@foreach (var group in Model.GroupBy(item => item.Entrydate))
{
        <th>
            @group.Key.Date
        </th>
}
        <th></th>
    </tr>
</thead>
<tbody>
@foreach (var group in Model.GroupBy(item => item.KeyTask)) {
    <tr>
        <td>
            @group.Key
        </td>
        @foreach (var item in group)
        {
            <td>
                @Html.DisplayFor(modelItem => item.Acceptable)
            </td>

        }
    </tr>
}
</tbody>
</table>

@DisplayNameFor(model=>model.KeyTask)
@foreach(Model.GroupBy(item=>item.Entrydate)中的var组)
{
@组键日期
}
@foreach(Model.GroupBy(item=>item.KeyTask)中的var组){
@组键
@foreach(组中的var项目)
{
@DisplayFor(modelItem=>item.Acceptable)
}
}
从我的成绩来看,我几乎达到了目标


我遗漏了一些东西,因为来自acceptance的数据与entrydate列不匹配。我走的是正确的道路,还是我已经走到了LINQ所能走的那么远,需要尝试另一种方法?

经过大量的搜索、阅读、尝试和错误,我找到了一种方法来实现这一点

首先,我意识到LINQ表达式不是我需要的方式。我需要单独构建行。由于数据具有动态列,DBSet无法工作。因此,我在SQL中构建了一个Pivot查询

DECLARE @cols NVARCHAR (MAX),
    @StartDate date = '03/01/2017',
    @EndDate date = '03/20/2017',
    @Id nvarchar(10) = 1

SELECT @cols = COALESCE (@cols + ',[' + CONVERT(NVARCHAR, entrydate, 106) + 
    ']', 
    '[' + CONVERT(NVARCHAR, entrydate, 106) + ']')
    FROM    (SELECT DISTINCT entrydate 
             FROM EmployeeTask 
             WHERE entrydate >= @StartDate AND entrydate <= @EndDate 
             AND EmployeeId = @Id) PV  
    ORDER BY entrydate DESC

DECLARE @query NVARCHAR(MAX)
SET @query = '          
          SELECT * FROM (SELECT KeyTask, acceptable, entrydate 
                         FROM EmployeeTask 
                         WHERE EmployeeId = ('+ @Id +')
                         Group by KeyTask, acceptable, entrydate) x
          PIVOT (SUM(acceptable) FOR entrydate IN (' + @cols + ')) p
             '     
EXEC SP_EXECUTESQL @query
接下来,我修改了视图:

@model List<Dictionary<string, object>>

@{
    ViewData["Title"] = "Employee Tasks";
}

<h2>Employee Tasks</h2>

<div class="panel panel-default">
<div class="panel-heading">Search by dates</div>
<div class="panel-body">
    <form asp-controller="EmployeeTasks" asp-action="Index">
        <label>Start Date</label>
        <input type="date" name="datestart" id="start" value=@ViewBag.start   
            />
        <label>End Date</label>
        <input type="date" name="dateend" id="end" value=@ViewBag.end />
        <input type="submit" value="Search" />
    </form>
   </div>
</div>

<p>
    <a asp-action="Create">Add New Employee Task</a>
</p>

@if (Model.FirstOrDefault() != null)
{
    <table class="table table-bordered">
    @foreach (var row in Model.FirstOrDefault())
    {
        <th>@row.Key</th>
    }
    @foreach (var row in Model)
    {
        <tr>
        @foreach (var column in row)
        {
            <td>@column.Value</td>  
        }
        </tr>
    }
</table>
}

<div>
    <a asp-controller="Employees" asp-action="Index">Back to Employee 
        Search</a>
</div>
@型号列表
@{
ViewData[“Title”]=“员工任务”;
}
员工任务
按日期搜索
开始日期
结束日期


如果有人有更简单的方法,请将其作为答案发布,以便我可以尝试,但这在.NET Core 1.1中非常有效。

经过多次搜索、阅读、反复尝试,我找到了一种方法来实现这一点

首先,我意识到LINQ表达式不是我需要的方式。我需要单独构建行。由于数据具有动态列,DBSet无法工作。因此,我在SQL中构建了一个Pivot查询

DECLARE @cols NVARCHAR (MAX),
    @StartDate date = '03/01/2017',
    @EndDate date = '03/20/2017',
    @Id nvarchar(10) = 1

SELECT @cols = COALESCE (@cols + ',[' + CONVERT(NVARCHAR, entrydate, 106) + 
    ']', 
    '[' + CONVERT(NVARCHAR, entrydate, 106) + ']')
    FROM    (SELECT DISTINCT entrydate 
             FROM EmployeeTask 
             WHERE entrydate >= @StartDate AND entrydate <= @EndDate 
             AND EmployeeId = @Id) PV  
    ORDER BY entrydate DESC

DECLARE @query NVARCHAR(MAX)
SET @query = '          
          SELECT * FROM (SELECT KeyTask, acceptable, entrydate 
                         FROM EmployeeTask 
                         WHERE EmployeeId = ('+ @Id +')
                         Group by KeyTask, acceptable, entrydate) x
          PIVOT (SUM(acceptable) FOR entrydate IN (' + @cols + ')) p
             '     
EXEC SP_EXECUTESQL @query
接下来,我修改了视图:

@model List<Dictionary<string, object>>

@{
    ViewData["Title"] = "Employee Tasks";
}

<h2>Employee Tasks</h2>

<div class="panel panel-default">
<div class="panel-heading">Search by dates</div>
<div class="panel-body">
    <form asp-controller="EmployeeTasks" asp-action="Index">
        <label>Start Date</label>
        <input type="date" name="datestart" id="start" value=@ViewBag.start   
            />
        <label>End Date</label>
        <input type="date" name="dateend" id="end" value=@ViewBag.end />
        <input type="submit" value="Search" />
    </form>
   </div>
</div>

<p>
    <a asp-action="Create">Add New Employee Task</a>
</p>

@if (Model.FirstOrDefault() != null)
{
    <table class="table table-bordered">
    @foreach (var row in Model.FirstOrDefault())
    {
        <th>@row.Key</th>
    }
    @foreach (var row in Model)
    {
        <tr>
        @foreach (var column in row)
        {
            <td>@column.Value</td>  
        }
        </tr>
    }
</table>
}

<div>
    <a asp-controller="Employees" asp-action="Index">Back to Employee 
        Search</a>
</div>
@型号列表
@{
ViewData[“Title”]=“员工任务”;
}
员工任务
按日期搜索
开始日期
结束日期


如果有人有更简单的方法,请将其作为答案发布,以便我可以尝试,但这在.NET Core 1.1中非常有效。

在Asp.NET Core code first方法中有更好的处理方法,因为您只需要在Sql server中创建相应的视图,如

CREATE VIEW VIEWNAME AS SELECT ENTRYDATE,COL1,COL2 FROM TABLES GROUP BY ENTRYDATE
然后,您只需要在web应用程序中创建一个与VIEWNAME同名的ViewModel类,然后需要在dbcontext类中调用这一行

public DbQuery<VIEWNAME> VIEWNAME { get; set; }

就是这样…干杯

在Asp.Net核心代码优先的方法中有一种更好的处理方法,因为您只需要在Sql server中创建相应的视图,如

CREATE VIEW VIEWNAME AS SELECT ENTRYDATE,COL1,COL2 FROM TABLES GROUP BY ENTRYDATE
然后,您只需要在web应用程序中创建一个与VIEWNAME同名的ViewModel类,然后需要在dbcontext类中调用这一行

public DbQuery<VIEWNAME> VIEWNAME { get; set; }

就是这样……干杯

你的分组结果在列和正文中是不同的,这意味着你不是在处理同一个分组结果,而这些分组结果应该在
EntryDate
@JS_GodBlessAll:将数字与行中的日期对齐,但行应该是任务。我认为这里最大的问题是,对于某些日期不可接受的任务,没有真正的空或零作为占位符。我试着一行一行地构建,但是由于日期列是动态的,所以我无法构建一个能够准确反映我需要捕获的内容的模型。我还尝试了使用我找到的SQL方法,但我似乎还不能使它工作。您的分组方式s在列和正文中是不同的,这意味着您没有处理相同的分组方式结果,而这些分组方式应该是通过
EntryDate
@JS_GodBlessAll:将数字与行中的日期对齐,但行应该是任务。我认为这里最大的问题是,对于某些日期不可接受的任务,没有真正的空或零作为占位符。我试着一行一行地构建,但是由于日期列是动态的,所以我无法构建一个能够准确反映我需要捕获的内容的模型。我还尝试使用我找到的SQL方法,但似乎还不能使它工作。