2016-05-17 29 views
0

我需要显示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?

https://stackoverflow.com/questions/26372533/add-the-list-of-object-to-parent-object-using-mvc-5-and-ef-6

任何帮助将是大大赞赏。

+0

您应该使用任何查询中,如: viewModel.PORequests = viewModel.PORequests.Where(X => x.POItems.Any( i => i.Description.Contains(ItemDescription)))。ToPagedList(pageNumber,5); –

+0

@ t.enix哎呀,我没有注意到你的评论。随意添加它作为答案,我会删除我的。 –

回答

1

深入到搜索表达式的项目:

if (!string.IsNullOrEmpty(ItemDescription)) 
{ 
    viewModel.PORequests = viewModel.PORequests.Where(x => x.POItems 
     .Any(i => i.Description.Contains(ItemDescription))) 
     .ToPagedList(pageNumber, 5); 
}