Можно ли каким-либо образом иметь несколько раскрывающихся меню, отображающих данные из одной и той же сущности базы данных на одной и той же странице бритвы, не создавая несколько классов с новыми идентификаторами (например, ResourceID; ResourceID1; ResourceID2)
IЯ могу отобразить раскрывающийся список с соответствующими данными из базы данных MS SQL на страницах бритвы «Create.cshtml» и «Edit.cshtml», но выбранные данные при сохранении отображают идентификатор выбранного ресурса вместо имениресурс в представлениях «Index.cshtml», «Detail.cshtml» и «Delete.cshtml».
Модель ресурса:
namespace ProjectReporting.Models
{
public class Resource
{
public int ID { get; set; }
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Long Name")]
public string LongName { get; set; }
[DefaultValue(true)]
[Display(Name = "Active")]
public bool IsActive { get; set; } = true;
[Display(Name = "Is Manager")]
public bool IsManager { get; set; }
[Display(Name = "Is Forecast Owner")]
public bool IsForecastOwner { get; set; }
public ICollection<Project> Projects { get; set; }
}
}
Модель проекта:
namespace ProjectReporting.Models
{
public class Project
{
public int ID { get; set; }
[Display(Name = "ID")]
public int PID { get; set; }
[Display(Name = "Project Name")]
public string ProjectName { get; set; }
[Display(Name = "Forecast Owner")]
public int ResourceID { get; set; }
public Resource Resource { get; set; }
[Display(Name = "DSM")]
public int? ResourceID1 { get; set; }
public ICollection<ProjectComment> ProjectComments { get; set; }
}
}
Страница Create.cshtml:
@page
@model ProjectReporting.Pages.Projects.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Project</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Project.PID" class="control-label"></label>
<input asp-for="Project.PID" class="form-control" />
<span asp-validation-for="Project.PID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Project.ProjectName" class="control-label"></label>
<input asp-for="Project.ProjectName" class="form-control" />
<span asp-validation-for="Project.ProjectName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Project.ResourceID" class="control-label"></label>
<select asp-for="Project.ResourceID" class="form-control" asp-items="ViewBag.ResourceID"><option value="" default="" selected="">-- Select --</option></select>
</div>
<div class="form-group">
<label asp-for="Project.ResourceID1" class="control-label"></label>
<select asp-for="Project.ResourceID1" class="form-control" asp-items="ViewBag.ResourceID1"><option value="" default="" selected="">-- Select --</option></select>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="Project.IsArchived" /> @Html.DisplayNameFor(model => model.Project.IsArchived)
</label>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Страница Create.cshtml:
namespace ProjectReporting.Pages.Projects
{
public class CreateModel : PageModel
{
private readonly ProjectReporting.Data.ApplicationDbContext _context;
public CreateModel(ProjectReporting.Data.ApplicationDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
ViewData["OrganisationID"] = new SelectList(_context.ProjectType.Where(a => a.IsActive == true), "ID", "TypeName");
ViewData["ResourceID"] = new SelectList(_context.Resource.Where(a => a.IsActive & a.IsForecastOwner == true), "ID", "LongName");
ViewData["ResourceID1"] = new SelectList(_context.Resource.Where(a => a.IsActive == true), "ID", "LongName");
return Page();
}
[BindProperty]
public Project Project { get; set; }
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Project.Add(Project);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
Страница Index.cshtml:
@page
@model ProjectReporting.Pages.Projects.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Project[0].PID)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].Organisation)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].ProjectName)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].Resource)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].ResourceID1)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].IsArchived)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Project) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.PID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Organisation.OrgName)
</td>
<td>
@Html.DisplayFor(modelItem => item.ProjectName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Resource.LongName)
</td>
<td>
@Html.DisplayFor(modelItem => c)
</td>
<td>
@Html.DisplayFor(modelItem => item.IsArchived)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Item.Resource.LongName отлично работает для первого ресурса, но я бы хотел, чтобы то же самое произошло с item.Resource.LongName.
Index.cshtml.cs
namespace ProjectReporting.Pages.Projects
{
public class IndexModel : PageModel
{
private readonly ProjectReporting.Data.ApplicationDbContext _context;
public IndexModel(ProjectReporting.Data.ApplicationDbContext context)
{
_context = context;
}
public IList<Project> Project { get;set; }
public async Task OnGetAsync()
{
Project = await _context.Project
.Include(p => p.Resource).ToListAsync();
}
}
}
Я установил FK в файле миграции для создания базы данныхиметь возможность извлекать данные и не создавать один файл класса по ресурсам.
table.ForeignKey(
name: "FK_Project_Resource_ResourceID",
column: x => x.ResourceID,
principalTable: "Resource",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Project_Resource_ResourceID1",
column: x => x.ResourceID1,
principalTable: "Resource",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
В результате отображаются правильные данные в раскрывающемся списке и правильный идентификатор ресурса, выбранный при сохранении. Тем не менее, индекс, подробности и страница удаления отображают только ResourceID вместо LongName. Если я использую Resource.LongName для второго ResourceID1, он по праву отображает тот же LongName, что и для ResourceID.
Как я могу иметь несколько раскрывающихся списков ресурсов на странице, которые указывают на одну и ту же сущность и отображать LongName наИндекс, детализация и удаление страниц?