ASP.NET-如何使用来自另一个模型的数据加载模型,该数据通过2个外键两次删除

时间:2018-11-27 18:29:30

标签: asp.net entity-framework-core

我很难弄清楚这个。

我有3个表,每个表都由外键链接。 JobDescription,TrainingMatrix和文档

我使用EF脚手架为这三个表构建了模型和控制器。

职位描述模型:

public partial class JobDescription
{
    public JobDescription()
    {
        JobPositions = new HashSet<JobPosition>();
        TrainingMatrices = new HashSet<TrainingMatrix>();
    }

    [Key]
    [Display(Name="ID")]
    public int JobDescId { get; set; }
    [Display(Name ="Title")]
    public string Title { get; set; }
    [Display(Name ="Status")]
    public string Status { get; set; }

    [Display(Name ="Job Position Document")]
    public string DocId { get; set; }

    [Display(Name = "Job Position Document")]
    public Document Doc { get; set; }
    public ICollection<JobPosition> JobPositions { get; set; }
    public ICollection<TrainingMatrix> TrainingMatrices { get; set; }

}

训练矩阵模型

public partial class TrainingMatrix
{
    public string DocId { get; set; }
    public int JobDescId { get; set; }

    public Document Doc { get; set; }
    public JobDescription JobDesc { get; set; }
}

文档模型

public partial class Document
{
    public Document()
    {
        TrainingMatrices = new HashSet<TrainingMatrix>();
        TrainingRecords = new HashSet<TrainingRecord>();
    }

    [DisplayName("ID")]
    public string DocId { get; set; }
    [DisplayName("Title")]
    public string Title { get; set; }
    [DisplayName("Vault Location")]
    public string VaultLocation { get; set; }
    [DisplayName("Type")]
    public string Type { get; set; }
    [DisplayName("Status")]
    public string Status { get; set; }

    public ICollection<JobDescription> JobDescriptions { get; set; }
    public ICollection<TrainingMatrix> TrainingMatrices { get; set; }
    public ICollection<TrainingRecord> TrainingRecords { get; set; }
}

我想做的是在视图中创建一个视图。 我正在尝试将训练矩阵视图放在工作描述详细信息视图中。

职位描述视图

@model PTI.Web.EPDM.TrainingInterface.Models.JobDescription

@{
    ViewData["Title"] = "Details";
}

<h2>Details</h2>

<div>
    <h4>Job Description</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Status)
        </dt>
        <dd>
            @switch (Model.Status)
            {
                case "A":
                    <text>Active</text>
                    break;
                case "O":
                    <text>Obsolete</text>
                    break;
                default:
                    break;
            }
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Doc)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Doc.DocId)
        </dd>
    </dl>
</div>
@{await Html.RenderPartialAsync("~/Views/TrainingMatrices/Index.cshtml", Model.TrainingMatrices, new ViewDataDictionary(ViewData)); }
<div>
    <a asp-action="Edit" asp-route-id="@Model.JobDescId">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

TrainingMatrix视图

@model IEnumerable<PTI.Web.EPDM.TrainingInterface.Models.TrainingMatrix>

@{

}

<h2>Related Documents</h2>

<table id="documentTable" class="table table-striped table-bordered" style="width:100%">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Doc.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Doc.VaultLocation)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Doc.Type)

            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Doc.Title)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Doc.VaultLocation)
                </td>
                <td>
                    @if(item.Doc.Type != null)
                    {
                    switch (item.Doc.Type)
                    {
                        case "FC":
                            <text>Form Control</text>
                            break;
                        case "AI":
                            <text>Action Item</text>
                            break;
                        case "WI":
                            <text>Work Instruction</text>
                            break;
                        case "CC":
                            <text>Customer Complaint</text>
                            break;
                        case "SOP":
                            <text>Standard Operating Procedure</text>
                            break;
                        case "JP":
                            <text>Job Position</text>
                            break;
                        default:
                            break;
                    }
                    }
                </td>
                <td>
                    <a class="btn btn-info" asp-action="Details" asp-route-id="@item.DocId" title="Details">
                        <i class="fas fa-eye" aria-hidden="true"></i>
                    </a>
                </td>
            </tr>
        }
    </tbody>
</table>

<script>
    $(document).ready(() => {
        $('#documentTable').DataTable();

    });
</script>

单独运行时,“训练矩阵”视图会正确加载,显示训练矩阵的所有文档信息,因为它正在运行控制器代码:

public async Task<IActionResult> Index()
{
    var applicationDbContext = _context.TrainingMatrices.Include(t => t.Doc).Include(t => t.JobDesc);
    return View(await applicationDbContext.ToListAsync());
}

但是当使用此控制器从“作业描述”页面作为部分视图运行时,它会崩溃,因为JobDescription.TrainingMatrices.Doc不存在,并抛出NullReferenceException:

public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    ViewData["DocId"] = new SelectList(_context.Documents.Where(d => d.Status == "A"), "DocId", "Title");

    JobDescription jobDescription = await _context.Descriptions
        .Include(j => j.Doc)
        .Include(j=>j.TrainingMatrices)
        .FirstOrDefaultAsync(m => m.JobDescId == id);


    if (jobDescription == null)
    {
        return NotFound();
    }
    ViewData["JobDescId"] = jobDescription.JobDescId;
    return View(jobDescription);
}

我需要做的是获取JobDescription控制器以填充JobDescription.TrainingMatrices.Doc值,或者让局部视图调用TrainingMatricesController

在此先感谢您提供的帮助。

1 个答案:

答案 0 :(得分:0)

您的设置让我感到困惑,但是如果我理解正确,请尝试:

JobDescription jobDescription = await _context.Descriptions
    .Include(j => j.Doc)
    .Include(j=>j.TrainingMatrices)
           .ThenInclude(t => t.Doc)
    .FirstOrDefaultAsync(m => m.JobDescId == id);