将多个搜索条件应用于带有下拉列表的剃须刀页面列表



在Visual Studio 2019 Web应用程序EF Core中,我有一个带有项目列表的剃刀页面。每个项目都有几列带有资源名称。我希望能够使用多个下拉列表进行过滤。我已经设法构建了页面和过滤器,但只有当我在两个下拉列表中选择一个条目时,它们才有效。如果我独立使用它们,我不会收到任何错误。这两个搜索字符串在 URL/Projects?fosearchString=1&dsmsearchString=0中正确显示,但如果我只使用其中一个下拉条目,结果不会更新。 我希望下拉过滤器能够独立并协同工作(例如,仅 FO、仅 DSM、FO 和 DSM 一起工作(。我怎样才能做到这一点?

我有资源模型:

public class Resource
{
[Display(Name = "ID")]
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; }
[Display(Name = "Active")]
public bool IsActive { get; set; }
public ICollection<ProjectResource> ProjectResources { get; set; }
}

项目模型:

public class Project
{
[Display(Name = "ID")]
public int Id { get; set; }
[Display(Name = "PID")]
public int PID { get; set; }
[Display(Name = "Name")]
public string ProjectName { get; set; }
[Display(Name = "Forecast Owner")]
public int FOId { get; set; }
public Resource Resource { get; set; }
[Display(Name = "DSM")]
public int DSMId { get; set; }
public Resource DSMResource { get; set; }
public ICollection<ProjectResource> ProjectResources { get; set; }
}

索引.cshtml.cs:

public IList<Project> Project { get; set; }
public IList<Resource> Resources { get; set; }
public SelectList FOOptions { get; set; }
public string CurrentFOFilter { get; set; }
public SelectList Options { get; set; }
public string CurrentDSMFilter { get; set; }
public async Task<IActionResult> OnGetAsync(List<int> fosearchString, List<int> dsmsearchString)
{
FOOptions = new SelectList(_context.Resource, nameof(Resource.Id), nameof(Resource.LongName));
List<int> CurrentFOFilter = fosearchString;
Options = new SelectList(_context.Resource, nameof(Resource.Id), nameof(Resource.LongName));
List<int> CurrentDSMFilter = dsmsearchString;
if (fosearchString.Count == 0 || fosearchString[0] == 0 && dsmsearchString.Count == 0 || dsmsearchString[0] == 0)
{
Resources = await _context.Resource.ToListAsync();
Project = await _context.Project
.Include(p => p.Resource).ToListAsync();
}
else
{
Resources = await _context.Resource.ToListAsync();
Project = await _context.Project
.Include(p => p.Resource)
.Where(s => fosearchString.Contains(s.FOId) && dsmsearchString.Contains(s.DSMId))
.ToListAsync();
}
return Page();
}

索引.cshtml:

<form asp-page="./Index" method="get">
<div class="dropdown col-4 no-gutters">
<div class="input-group mb-3">
<select class="custom-select" name="fosearchString" value="@Model.CurrentFOFilter" asp-items="Model.FOOptions" selected="selected"><option value="0">Filter by FO...</option></select><text>&nbsp;</text>
<select class="custom-select" name="dsmsearchString" value="@Model.CurrentDSMFilter" asp-items="Model.Options" selected="selected"><option value="0">Filter by DSM...</option></select><text>&nbsp;</text>
</div>
<input type="submit" value="Filter" class="btn btn-primary" /><text>&nbsp;</text><input type="submit" action="/Projects/Index" value="Back to full List" class="btn btn-primary" />
</div>
</form>
<br />
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Project[0].PID)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].ProjectName)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].FOId)
</th>
<th>
@Html.DisplayNameFor(model => model.Project[0].DSMId)
</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.ProjectName)
</td>
<td>
@{
var foresource = Model.Resources.FirstOrDefault(r => r.Id == item.FOId);
}
@foresource.LongName
</td>
<td>
@{
var dsmresource = Model.Resources.FirstOrDefault(r => r.Id == item.DSMId);
}
@dsmresource.LongName
</td>

我使用名为ProjectVM和ResourceVM的两个视图模型将两个模型组合在一起,并且还通过ProjectResource类设置了两个模型之间的多对多关系。

问题在于您的ifelse条件,此外,您需要添加括号,因为&&||之前。

您始终可以添加断点来检查筛选时它进入的条件。

以下可行的解决方案是将第一个选项值设置为""而不是0这将更方便地搜索所有选项:

Index.cshtml:

<div class="input-group mb-3">
<select class="custom-select" name="fosearchString" value="@Model.CurrentFOFilter" asp-items="Model.FOOptions" selected="selected"><option value="">Filter by FO...</option></select><text>&nbsp;</text>
<select class="custom-select" name="dsmsearchString" value="@Model.CurrentDSMFilter" asp-items="Model.Options" selected="selected"><option value="">Filter by DSM...</option></select><text>&nbsp;</text>
</div>

Index.cshtml.cs:

public async Task<IActionResult> OnGetAsync(List<int> fosearchString, List<int> dsmsearchString)
{
FOOptions = new SelectList(_context.Resource, nameof(Resource.ID), nameof(Resource.LongName));
List<int> CurrentFOFilter = fosearchString;
Options = new SelectList(_context.Resource, nameof(Resource.ID), nameof(Resource.LongName));
List<int> CurrentDSMFilter = dsmsearchString;
if (fosearchString.Count == 0 && dsmsearchString.Count == 0)
{
Resources = await _context.Resource.ToListAsync();
Project = await _context.Project.Include(p => p.Resource).ToListAsync();
}
else if(fosearchString.Count != 0 && dsmsearchString.Count == 0)
{
Resources = await _context.Resource.ToListAsync();
Project = await _context.Project
.Include(p => p.Resource)
.Where(s => fosearchString.Contains(s.FOId))
.ToListAsync();
}
else if (fosearchString.Count == 0 && dsmsearchString.Count != 0)
{
Resources = await _context.Resource.ToListAsync();
Project = await _context.Project
.Include(p => p.Resource)
.Where(s => dsmsearchString.Contains(s.DSMId))
.ToListAsync();
}
else
{
Resources = await _context.Resource.ToListAsync();
Project = await _context.Project
.Include(p => p.Resource)
.Where(s => fosearchString.Contains(s.FOId) && dsmsearchString.Contains(s.DSMId))
.ToListAsync();
}
return Page();
}

最新更新