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



我很难弄清楚这一点。

我有三张表,每张表用外键连接。作业描述、培训矩阵和文档

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

培训矩阵视图

@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值,要么让部分视图调用TrainingMatricsController

提前感谢您的帮助。

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

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

最新更新