ASP.NET - Как загрузить модель с данными из другой модели, которая дважды удаляется через 2 внешних ключа - PullRequest
0 голосов
/ 27 ноября 2018

У меня проблемы с выяснением этого.

У меня есть 3 таблицы, каждая из которых связана внешним ключом.JobDescription, TrainingMatrix и Document

Я использовал леса 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 голосов
/ 27 ноября 2018

Ваша настройка сбивает меня с толку, но если я правильно понимаю, попробуйте:

JobDescription jobDescription = await _context.Descriptions
    .Include(j => j.Doc)
    .Include(j=>j.TrainingMatrices)
           .ThenInclude(t => t.Doc)
    .FirstOrDefaultAsync(m => m.JobDescId == id);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...