我有一个Inventory类,它不仅包含自己的字段,还包含其他类的几个引用ID。
public class Inventory {
public int Id { get; set; }
public string RtNum { get; set; }
public string AcntNum { get; set; }
public string CardNum { get; set; }
public string Num { get; set; }
[Range(1,3)]
public int Type { get; set; }
public int CompanyId { get; set; }
public int BranchId { get; set; }
public int PersonId { get; set; } }
在我的操作中,我从其他类生成了几个相关字段的IEnumerable列表。我还有几个非列表值要传递给View。我知道如何创建一个ViewModel来将所有内容传递给webgrid但无法遍历列表。我也知道如何将索引自动映射到一个列表,请参阅How to display row number in MVC WebGrid。 你如何将两者结合起来,以便可以使用索引迭代多个列表?
更新#1(更多细节)
public class Company {
public int Id { get; set; }
public string Name { get; set; } }
public class Branch {
public int Id { get; set; }
public string Name { get; set; } }
public class Person {
public int Id { get; set; }
public string Name { get; set; } }
public class MyViewModel {
public int PageNumber { get; set; }
public int TotalRows { get; set; }
public int PageSize { get; set; }
public IEnumerable<Inventory> Inventories { get; set; }
public int Index { get; set; }
public IEnumerable<string> CmpNm { get; set; }
public IEnumerable<string> BrnNm { get; set; }
public IEnumerable<string> PrnNm { get; set; } }
控制器
public class InventoryController : Controller
{ // I have a paged gird who’s code is not relevant to this discussion but a pagenumber,
// pagesize and totalrows will be generated
private ProjectContext _db = new ProjectContext();
public ActionResult Index() {
IEnumerable<Inventory> inventories = _db.Inventories;
List<string> cmpNm = new List<string>; List<string> brnNm = new List<string>; List<string> prnNm = new List<string>;
foreach (var item in inventories) { string x1 = "";
Company cmps = _db. Company.SingleOrDefault(i => i.Id == item.CompanyId); if (cmps!= null)
{ x1 = cmps.Name; } cmpNm.Add(x1); x1 = "";
Branch brns = _db. Branch.SingleOrDefault(i => i.Id == item. Branch Id); if (brns!= null) { x1 = brns.Name; } brnNm.Add(x1); x1 = "";
Person pers = _db.Persons.SingleOrDefault(i => i.Id == item. PersonId);
if (pers!= null) { x1 = pers.Name; } prnNm.Add(x1);
// the MyViewModel now needs to populated with all its properties and generate an index
// something along the line of
new MyViewModel { PageNumber= pagenumber, PageSize= pagesize, TotalRows=Totalrows, Inventories = inventories; CmpNm=cmpNm, BrnNm=brnNm, PrnNm=prnNm}
查看(如何创建索引是问题)
@model.Project.ViewModels.MyViewModel
@{ var grid = new WebGrid(Model.Inventories, Model.TotalRows, rowsPerPage: Model.PageSize); }
@grid.GetHtml( columns: grid.Columns(
Grid.Column(“PrnNm”, header: "Person", format: @Model.PrnNm.ElementAt(Index))
Grid.Column(“BrnNm”, header: "Branch", format: @Model.BrnNm.ElementAt(Index))
Grid.Column(“CmpNm”, header: "Company", format: @Model.CmpNm.ElementAt(Index))
grid.Column("RtNum", header: "Route"),
grid.Column("AcntNum", header: "Account"),
grid.Column("CardNum", header: "Card")
… ) )
网格应该是什么样子是不言而喻的。
答案 0 :(得分:2)
目前还不清楚你的目标是什么。但无论它是什么,我建议你定义一个真实的视图模型,反映你的视图的要求,只包含你有兴趣在这个网格中看到的信息:
public class InventoryViewModel
{
public int Id { get; set; }
public string PersonName { get; set; }
public string BranchName { get; set; }
public string CompanyName { get; set; }
public string RouteNumber { get; set; }
public string AccountNumber { get; set; }
public string CardNumber { get; set; }
}
现在您可以拥有主视图模型:
public class MyViewModel
{
public int PageNumber { get; set; }
public int TotalRows { get; set; }
public IEnumerable<InventoryViewModel> Inventories { get; set; }
}
好的,现在看来很明显:
@model MyViewModel
@{
var grid = new WebGrid(
Model.Inventories,
rowsPerPage: Model.PageSize
);
}
@grid.GetHtml(
columns: grid.Columns(
grid.Column("Id", header: "Inventory id"),
grid.Column("PersonName", header: "Person"),
grid.Column("BranchName", header: "Branch"),
grid.Column("CompanyName", header: "Company"),
grid.Column("RouteNumber", header: "Route"),
grid.Column("AccountNumber", header: "Account"),
grid.Column("CardNumber", header: "Card")
)
)
现在剩下的就是在你的控制器中构建这个视图模型。由于我不知道你想要在这里实现什么,无论你需要在这些列上使用内连接还是左外连接,我将以左外连接为例:
public ActionResult Index()
{
var inventories =
from inventory in _db.Inventories
join person in _db.Persons on inventory.PersonId equals person.Id into outerPerson
join company in _db.Companies on inventory.CompanyId equals company.Id into outerCompany
join branch in _db.Branch on inventory.BranchId equals branch.Id into outerBranch
from p in outerPerson.DefaultIfEmpty()
from c in outerCompany.DefaultIfEmpty()
from b in outerBranch.DefaultIfEmpty()
select new InventoryViewModel
{
PersonName = (p == null) ? string.Empty : p.Name,
CompanyName = (c == null) ? string.Empty : c.Name,
BranchName = (b == null) ? string.Empty : b.Name,
Id = inventory.Id,
AccountNumber = inventory.AcntNum,
CardNumber = inventory.CardNum,
RouteNumber = inventory.RtNum
};
var model = new MyViewModel
{
PageSize = 5,
// TODO: paging
Inventories = inventories.ToList()
};
return View(model);
}
这就是它。当然,在这个例子中,我将为您保留Inventories系列的分页。现在.Skip()
和.Take()
所需的记录数量应该非常简单。
正如您所看到的,ASP.NET MVC非常简单。您可以定义视图模型以反映需要在视图中显示的内容的确切要求,然后在控制器中填充此视图模型。大多数人都避免使用视图模型,因为他们无法填充它们,可能是因为他们缺乏对所使用的底层数据访问技术的了解。正如您在本示例中所看到的,困难并不在于ASP.NET MVC。它位于LINQ查询中。但LINQ严格与MVC无关。除了MVC之外,还应该学习它。当你做MVC时,总是要考虑视图模型以及需要向用户呈现的信息。不要考虑数据库中的内容或信息的来源。