2016-05-17 36 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); 
}