有什么办法可以让多个下拉菜单在同一个剃须刀页面上显示来自同一个数据库实体的数据,而无需创建多个具有新 ID 的类(例如 ResourceID;ResourceID1;ResourceID2)
我可以在“Create.cshtml”和“Edit.cshtml”剃须刀页面中显示来自 MS SQL 数据库的适当数据的下拉列表,但保存时选择的数据显示所选资源的 ID 而不是名称“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);
结果显示下拉列表中的正确数据以及保存时选择的正确资源 ID。但是,索引、详细信息和删除页面仅显示 ResourceID 而不是 LongName。如果我对第二个 ResourceID1 使用 Resource.LongName,它会正确显示与 ResourceID 相同的 LongName。
如何在页面上有多个指向同一实体的资源下拉列表并在索引、详细信息和删除页面上显示 LongName?