我需要显示PO请求的结果表,其中包括PO项目(我计算了此部分),并为显示的所有项目提供搜索功能部分我主要是想通了)。MVC 5 EF 6 - 如何使用相关表对象标准来搜索表格
使用下面的代码,这是一个稍微剥离的版本,我能够显示我需要的数据,并且我能够搜索几乎所有我需要的,只要它是来自PORequests模型的数据(this是“父母模型”)。当我尝试使用“子模型”POItems进行搜索时,实际对象(ID,说明等)无法访问。这是使用DatabaseFirst模型和EF6.x DbContextGenerator构建的。
//POItemData ViewModel
using FinanceSearch.Models;
namespace FinanceSearch.ViewModels
{
public class POItemData
{
public PagedList.IPagedList<PORequest> PORequests { get; set; }
public PagedList.IPagedList<POItem> POItems { get; set; }
}
}
//POItems Model
namespace FinanceSearch.Models
{
using System;
using System.Collections.Generic;
public partial class POItem
{
public int ID { get; set; }
public int Amount { get; set; }
public string Description { get; set; }
public virtual PORequest PORequest { get; set; }
}
}
//PORequest Model
namespace FinanceSearch.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class PORequest
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public PORequest()
{
this.POAttachments = new HashSet<POAttachment>();
this.POItems = new HashSet<POItem>();
}
//other relevant stuff
public virtual ICollection<POItem> POItems { get; set; }
}
}
//Controller
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using FinanceSearch.Models;
using PagedList;
using System.Web.UI.WebControls;
using System.Data.Entity.SqlServer;
using FinanceSearch.ViewModels;
namespace FinanceSearch.Controllers
{
public class PORequestsController : Controller
{
private Finance db = new Finance();
public ActionResult Index(int? id, int? page, string sortOrder, string currentFilter, string poNumber,
string AppropNumber, string ContractNumber, string ItemDescription)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.POSortParm = String.IsNullOrEmpty(sortOrder) ? "PONumber_desc" : "";
ViewBag.AppropNumberSortParm = sortOrder == "AppropNumber" ? "AppropNumber_desc" : "AppropNumber";
ViewBag.ContractNumberSortParm = sortOrder == "ContractNumber" ? "ContractNumber_desc" : "ContractNumber";
if (poNumber != null)
{
page = 1;
}
else
{
ponumber = currentFilter;
}
//int pageSize = 3;
int pageNumber = (page ?? 1);
var viewModel = new POItemData();
viewModel.PORequests = db.PORequests
.Include(i => i.POItems)
.OrderBy(i => i.ID).ToPagedList(pageNumber, 5);
if (!String.IsNullOrEmpty(poNumber))
{
viewModel.PORequests = viewModel.PORequests.Where(s => s.PONumber.Contains(ponumber)).ToPagedList(pageNumber, 5);
}
if (!string.IsNullOrEmpty(AppropNumber))
{
viewModel.PORequests = viewModel.PORequests.Where(x => x.AppropNumber.Contains(AppropNumber)).ToPagedList(pageNumber, 5);
}
if (!string.IsNullOrEmpty(ContractNumber))
{
viewModel.PORequests = viewModel.PORequests.Where(x => x.ContractNumber.Contains(ContractNumber)).ToPagedList(pageNumber, 5);
}
if (!string.IsNullOrEmpty(ItemDescription))
{
}
在ItemDescription if语句,像下面将是不错:
if (!string.IsNullOrEmpty(ItemDescription))
{
viewModel.PORequests = viewModel.PORequests.Where(x => x.POItems.Description.Contains(ItemDescription)).ToPagedList(pageNumber, 5);
}
的x.POItems.Description部分没有在这个意义上存在。显然与它是一个列表有关。继续代码其余...
switch (sortOrder)
{
case "PONumber_desc":
viewModel.PORequests = viewModel.PORequests.OrderByDescending(s => s.PONumber).ToPagedList(pageNumber, 5);
break;
case "AppropNumber":
viewModel.PORequests = viewModel.PORequests.OrderBy(s => s.AppropNumber).ToPagedList(pageNumber, 5);
break;
case "AppropNumber_desc":
viewModel.PORequests = viewModel.PORequests.OrderByDescending(s => s.AppropNumber).ToPagedList(pageNumber, 5);
break;
case "ContractNumber":
viewModel.PORequests = viewModel.PORequests.OrderBy(s => s.ContractNumber).ToPagedList(pageNumber, 5);
break;
case "ContractNumber_desc":
viewModel.PORequests = viewModel.PORequests.OrderByDescending(s => s.ContractNumber).ToPagedList(pageNumber, 5);
break;
default:
viewModel.PORequests = viewModel.PORequests.OrderBy(s => s.PONumber).ToPagedList(pageNumber, 5);
break;
}
return View(viewModel);
}
在上面的代码中,我包括我的分页和排序的东西为好,因为在教程和答案我也碰到过,这似乎使这一切是如何的不同事实证明,这是该项目所需要的。
下面是指数/查看我使用的显示结果:
//View (Index)
@model FinanceSearch.ViewModels.POItemData
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
ViewBag.Title = "PORequests";
}
<h2>Finance</h2>
@*<p>
@Html.ActionLink("Create New", "Create")
</p>*@
<p>
<button class="btn btn-default" data-toggle="collapse" href="#MainFilter" @*data-target="#MainFilter"*@ aria-multiselectable="true" aria-expanded="true">Filter By...</button>
</p>
@*<div id="accordion" role="tablist" aria-multiselectable="true">*@
@using (Html.BeginForm("Index", "PORequests", FormMethod.Get))
{
<div id="MainFilter" class="collapse">
<table class="table-responsive">
<tr>
<td>
Item:
</td>
<td>
@Html.TextBox("ItemDescription", ViewBag.CurrentFilter as string) //this is where the user would search items using a string
</td>
</tr>
<tr>
<td>
PO #:
</td>
<td>
@Html.TextBox("PONumber", ViewBag.CurrentFilter as string)
</td>
</tr>
</table>
<br />
<p>
<button class="btn btn-primary btn-sm" data-parent="#MainFilter" data-toggle="collapse" href="#SubFilterPOInfo" @*data-target="#SubFilterPOInfo"*@>Filter by PO Info...</button>
</p>
<div id="SubFilterPOInfo" class="collapse">
<table class="table-responsive">
<tr>
<td>
AppropNumber:
</td>
<td>
@Html.TextBox("AppropNumber", ViewBag.CurrentFilter as string)
</td>
</tr>
<tr>
<td>
Contract Number:
</td>
<td>
@Html.TextBox("ContractNumber", ViewBag.CurrentFilter as string)
</td>
</tr>
</table>
</div>
}
<div style="overflow-x: scroll">
<table class="table" style="white-space:nowrap">
<tr>
<th></th>
<th></th>
<th>
@Html.ActionLink("PONumber", "Index", new { sortOrder = ViewBag.POSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("AppropNumber", "Index", new { sortOrder = ViewBag.AppropNumberSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("ContractNumber", "Index", new { sortOrder = ViewBag.ContractNumberSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
</tr>
@foreach (var item in Model.PORequests)
{
<tr>
<td>
@*@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |*@
@Html.ActionLink("Details", "Details", new { id = item.ID }) |
@*@Html.ActionLink("Delete", "Delete", new { id = item.ID })*@
</td>
<td>
//I am able to list the related items in the PORequests table
@foreach (var poitem in item.POItems)
{
@poitem.Description<br />
}
</td>
<td>
@Html.DisplayFor(modelItem => item.PONumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.AppropNumber)
</td>
<td>
@Html.DisplayFor(modelItem => item.ContractNumber)
</td>
</tr>
}
</table>
</div>
<br />
//paging and sorting stuff
Page @(Model.PORequests.PageCount < Model.PORequests.PageNumber ? 0 : Model.PORequests.PageNumber) of @Model.PORequests.PageCount
@Html.PagedListPager(Model.PORequests, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
总结:
我似乎并不理解如何使用变量ItemDescription到在POItems列表中搜索,并获取包含POItem表作为相关对象的PORequest表,以显示结果。我的其他搜索全部按预期运行。
我已经在这个网站上特别搜索过,但任何类似的问题都涉及到查看结束,只是显示列表中的每个项目,我可以做什么,创建/编辑功能,或者,他们超出了我对MVC的理解,因为他们似乎并不是解决方案。
这里有几个这样的例子:
MVC Code First: One-to-many relationship between own model and SimpleMembership user
EntityFramework 6. How to get related objects?
任何帮助将是大大赞赏。
您应该使用任何查询中,如: viewModel.PORequests = viewModel.PORequests.Where(X => x.POItems.Any( i => i.Description.Contains(ItemDescription)))。ToPagedList(pageNumber,5); –
@ t.enix哎呀,我没有注意到你的评论。随意添加它作为答案,我会删除我的。 –