C# 在MVC中组合2个通用列表时,无法将列表转换为IEnumerable#
我有两个由C# 在MVC中组合2个通用列表时,无法将列表转换为IEnumerable#,c#,linq,model-view-controller,C#,Linq,Model View Controller,我有两个由LINQ使用ViewModels生成的列表,我想将它们合并成一个列表并显示在主视图的数据表中。我分别测试了这两个列表,它们都带来了我期望的结果。我找到了几种组合列表的方法,但我无法组合列表以发送回我的视图。有人能帮我找到答案吗 使用下面的代码,我有智能感知告诉我list.AddRange(personellist)和列表.AddRange(非个人列表)p.LastUpdateDate); 返回视图(viewModel); 无论是否创建自己的基类,列表中的每个项都必须转换为正确的类型才
LINQ
使用ViewModels
生成的列表,我想将它们合并成一个列表并显示在主视图的数据表中。我分别测试了这两个列表,它们都带来了我期望的结果。我找到了几种组合列表的方法,但我无法组合列表以发送回我的视图。有人能帮我找到答案吗
使用下面的代码,我有智能感知告诉我list.AddRange(personellist)代码>和列表.AddRange(非个人列表)你错了。问题是它无法从Generic.List转换为Generic.IEnumerable
控制器:
List<PersonnelViewModel> personnelList = (from p in db.Personnel
where p.ActiveFG == true
join pd in db.PersonnelDetail on p.ID equals pd.PersonnelID into pdGroup
from pdItem in pdGroup.DefaultIfEmpty()
join pos in db.Position on p.PrimaryPositionID equals pos.ID into posGroup
from posItem in posGroup.DefaultIfEmpty()
join d in db.Department on posItem.DepartmentID equals d.ID into dGroup
from dItem in dGroup.DefaultIfEmpty()
join l in db.Locations on p.PrimaryLocation equals l.ID into lGroup
from lItem in lGroup.DefaultIfEmpty()
join b in db.Building on lItem.BuildingID equals b.ID into bGroup
from bItem in bGroup.DefaultIfEmpty()
join f in db.FaxMachine on pdItem.FaxID equals f.ID into fGroup
from fItem in fGroup.DefaultIfEmpty()
select new PersonnelViewModel
{
ID = p.ID,
DisplayName = p.DisplayName ?? string.Empty,
EmailAddress = p.EmailAddress ?? string.Empty,
PhotoLocation = p.PhotoLocation ?? string.Empty,
PortNumber = pdItem.PhonePort ?? string.Empty,
SwitchPort = pdItem.SwitchPort ?? string.Empty,
PrimaryPositionTitle = posItem.PositionTitle ?? string.Empty,
Supervisor = db.Personnel.Where(p => p.ID == posItem.SupervisorID).Select(n => n.DisplayName).FirstOrDefault(),
PrimaryDepartmentName = dItem.DepartmentName ?? string.Empty,
DirectoryAssistant = db.Personnel.Where(p => p.ID == dItem.DirectoryAssistantPositionID).Select(n => n.DisplayName).FirstOrDefault(),
PrimaryRoomNumber = lItem.RoomNumber ?? string.Empty,
PrimaryBuildingName = bItem.BuildingName ?? string.Empty,
FaxNumber = fItem.Number ?? string.Empty,
BuildingMonitor = (bool)pdItem.BuildingMonitor,
CPRTrained = (bool)pdItem.CPRTrained,
CPRTrainedExpirationDate = pdItem.CPRTrainedExpirationDate ?? default(DateTime),
DirectDial = (bool)pdItem.DirectDial,
AEDTrained = (bool)pdItem.DefibrillatorTrained,
AEDTrainedExpirationDate = pdItem.DefibrillatorTrainedExpirationDate ?? default(DateTime),
PrimaryExtension = (int)pdItem.Extension,
NotaryPublic = (bool)pdItem.NotaryPublic,
NotaryPublicExpirationDate = pdItem.NotaryPublicExpirationDate ?? default(DateTime),
ActiveFG = (bool)p.ActiveFG,
Person = true,
LastUpdatedBy = p.LastUpdatedBy,
LastUpdatedDate = p.LastUpdatedDate.Value,
}).ToList();
List<NonPersonnelViewModel> nonPersonnelList = (from np in db.NonPersonnel
where np.ActiveFG == true
join npt in db.NonPersonnelTypes on np.NonPersonnelTypesID equals npt.ID into nptGroup
from nptItem in nptGroup.DefaultIfEmpty()
join dpt in db.Department on np.DepartmentID equals dpt.ID into dptGroup
from dptItem in dptGroup.DefaultIfEmpty()
join a in db.Area on dptItem.AreaID equals a.ID into aGroup
from aItem in aGroup.DefaultIfEmpty()
join div in db.Division on aItem.DivisionID equals div.ID into divGroup
from divItem in divGroup.DefaultIfEmpty()
join l in db.Locations on np.LocationID equals l.ID into lGroup
from lItem in lGroup.DefaultIfEmpty()
join b in db.Building on lItem.BuildingID equals b.ID into bGroup
from bItem in bGroup.DefaultIfEmpty()
join s in db.Sites on bItem.SiteID equals s.ID into sGroup
from sItem in sGroup.DefaultIfEmpty()
select new NonPersonnelViewModel
{
ID = np.ID,
NonPersonnelDescription = nptItem.NonPersonnelDescription ?? string.Empty,
DepartmentName = dptItem.DepartmentName ?? string.Empty,
DivisionName = divItem.DivisionName ?? string.Empty,
AreaName = aItem.AreaName ?? string.Empty,
Site = string.Concat((sItem.AddressLine1 ?? string.Empty) + Environment.NewLine + (sItem.AddressLine2 ?? string.Empty) + Environment.NewLine +
(sItem.City ?? string.Empty) + " " + (sItem.State ?? string.Empty) + ", " + (sItem.Zip ?? string.Empty)),
Switchboard = sItem.Switchboard ?? string.Empty,
DirectoryAssistant = db.Personnel.Where(p => p.ID == dptItem.DirectoryAssistantPositionID).Select(n => n.DisplayName).FirstOrDefault(),
RoomNumber = lItem.RoomNumber ?? string.Empty,
BuildingName = bItem.BuildingName ?? string.Empty,
Person = false,
ActiveFG = (bool)np.ActiveFG,
LastUpdatedBy = np.LastUpdatedBy,
LastUpdatedDate = np.LastUpdatedDate.Value,
}).ToList();
List<HomeViewModel> list = new List<HomeViewModel>();
list.AddRange(personnelList);
list.AddRange(nonPersonnelList);
// combine lists to show in master list on home page
return View(list);
视图模型:
public class HomeViewModel
{
public List<PersonnelViewModel> PersonnelList { get; set; }
public List<NonPersonnelViewModel> NonPersonnelList { get; set; }
}
public class IndexViewModel
{
// personnel //
public string NamePrefix { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string NameSuffix { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
public string PhotoLocation { get; set; }
public string PositionTitle { get; set; }
public string SecondaryPositionTitle { get; set; }
public string SecondaryDepartmentName { get; set; }
public string SecondaryDivisionName { get; set; }
public string SecondaryAreaName { get; set; }
public int SecondaryExtension { get; set; }
public string SecondaryBuildingName { get; set; }
public string SecondaryRoomNumber { get; set; }
public string EmailAddress { get; set; }
public string Supervisor { get; set; }
public string SecondaryLocation { get; set; }
public string FaxNumber { get; set; }
public int Voicemail { get; set; }
public string PortNumber { get; set; }
public string SwitchPort { get; set; }
public bool DirectDial { get; set; }
public bool BuildingMonitor { get; set; }
public bool NotaryPublic { get; set; }
public DateTime NotaryPublicExpirationDate { get; set; }
public bool CPRTrained { get; set; }
public DateTime CPRTrainedExpirationDate { get; set; }
public bool AEDTrained { get; set; } // DefibrillatorTrained
public DateTime AEDTrainedExpirationDate { get; set; } // DefibrillatorTrainedExpirationDate
// both //
public int ID { get; set; }
public string DisplayName { get; set; }
public string DepartmentName { get; set; }
public string DivisionName { get; set; }
public string AreaName { get; set; }
public int Extension { get; set; }
public string BuildingName { get; set; }
public string RoomNumber { get; set; }
public string Location { get; set; }
public string Site { get; set; }
public string Switchboard { get; set; }
public string DirectoryAssistant { get; set; }
public string MailboxLocation { get; set; }
public bool ActiveFG { get; set; }
public bool Person { get; set; }
public string LastUpdatedBy { get; set; }
public DateTime LastUpdatedDate { get; set; }
}
看起来您正试图将两个列表强制添加到需要列表的视图的视图模型中。虽然使用列表作为视图模型似乎是一种常见的做法,但我发现从长远来看,它不太可维护,最好从一开始就创建一个视图特定的视图模型类作为容器。始终存在这样的可能性,即您以后必须向视图模型添加某些内容,如果您只需添加属性,则更容易进行调整
问题是,你就快到了。您有HomeViewModel
,它将两个列表都作为属性。您所需要做的就是(至少在action方法中)填充属性并将其交给视图
HomeViewModel viewModel=新的HomeViewModel()
{
personellist=personellist,
非人员专家=非人员专家
};
返回视图(viewModel);
在您的视图中,更改模型类型,您将有model.personellist
和model.nonpersonellist
可用
@model <whatever the namespace is>.HomeViewModel
作为旁注,关于这是HomeController
中的Index
操作方法的猜测,我建议将HomeViewModel
重命名为IndexViewModel
,并将其放入Models
文件夹下的HomeModels
文件夹中。这种组织类的方式将有助于保持视图模型和相关类的组织
一点妥协
如果你真的需要把它们放在同一个列表中,那就不那么直截了当了,但这是可能的
必须声明列表以保存可分配给公共类型的实例<代码>列表
将适用于您现在拥有的内容,因为它们基本上没有共同点。那不太好
您可以声明一个基类,例如BasePersonViewModel
,并将一些常用属性移动到它,例如ID
、ActiveFG
、Person
、LastUpdateBy
、以及LastUpdateDate
。这将允许您对它们进行一些处理,例如按lastUpdateDate
排序。(目前还不清楚“非人员”是一种不同类型的人还是一种非人员的东西,所以名字可能不对——请耐心听我说。)
IEnumerable viewModel=personal.AsEnumerable()
.Concat(非人员)
.OrderByDescending(p=>p.LastUpdateDate);
返回视图(viewModel);
无论是否创建自己的基类,列表中的每个项都必须转换为正确的类型才能使用其属性
@*假设模型是列表*@
@foreach(模型中的BasePersonViewModel项)
{
@*显示常用数据,如item.ID*@
@if(项目为人员查看模型人员)
{
@*显示“人员”数据*@
}
else if(项目为非人员查看模型非人员)
{
@*显示“非人员”数据*@
}
}
话虽如此,如果可能的话,您应该使用单独的列表。您确定这是完整的错误信息吗?因为看起来您试图将一种类型的项添加到包含不同类型项的列表中。personalviewmodel
是非personalviewmodel
的基类,还是反之亦然?它们都有共同的基类吗?你能告诉我们“用IList更新HomeViewModel”在代码方面意味着什么吗?我将public List personnelist{get;set;}
更改为public IList personnelist{get;set;}
并将LINQ
语句更新为select new PersonnelViewModel。ToEnumerable().ToList()
这些类型有什么共同点吗?如果它们是不同的类型,为什么你认为它们可以合并到同一个列表中?@Jamie为什么不为两者使用相同的viewmodel类?为它提供所有需要的属性,包括IsPersonel bool标志。然后它们可以互换,可以放在同一个列表中,等等。@EdPlunkett上周我第一次开始这个项目时,实际上正试图建立一个具有这两个属性的ViewModel
,后来掉进了谷歌的兔子洞,改变了主意。很高兴看到我走上了正确的道路。我尝试了第一个建议,即将列表发送回视图,并确保声明是@model IEnumerable
(我根据您的建议将其重命名),但当我尝试在视图中使用model.personellist
或model.nonpersonellist
时,intellisense告诉我,IEnumerable不包含Personnelist的定义,并且找不到接受IEnumerable类型第一个参数的可访问扩展方法
您知道它为什么会这样说吗?它应该是@model IndexViewModel
,以匹配传递给视图的对象的类型(…)
方法。感谢所有的帮助和建议!最后,我将个人视图模型
和非个人视图模型
中的所有数据合并到索引模型
中,并找到了相似之处,然后更新了我的家庭控制器
,将个人视图
和非个人视图
合并,发送回视图a
public class IndexViewModel
{
// personnel //
public string NamePrefix { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string NameSuffix { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
public string PhotoLocation { get; set; }
public string PositionTitle { get; set; }
public string SecondaryPositionTitle { get; set; }
public string SecondaryDepartmentName { get; set; }
public string SecondaryDivisionName { get; set; }
public string SecondaryAreaName { get; set; }
public int SecondaryExtension { get; set; }
public string SecondaryBuildingName { get; set; }
public string SecondaryRoomNumber { get; set; }
public string EmailAddress { get; set; }
public string Supervisor { get; set; }
public string SecondaryLocation { get; set; }
public string FaxNumber { get; set; }
public int Voicemail { get; set; }
public string PortNumber { get; set; }
public string SwitchPort { get; set; }
public bool DirectDial { get; set; }
public bool BuildingMonitor { get; set; }
public bool NotaryPublic { get; set; }
public DateTime NotaryPublicExpirationDate { get; set; }
public bool CPRTrained { get; set; }
public DateTime CPRTrainedExpirationDate { get; set; }
public bool AEDTrained { get; set; } // DefibrillatorTrained
public DateTime AEDTrainedExpirationDate { get; set; } // DefibrillatorTrainedExpirationDate
// both //
public int ID { get; set; }
public string DisplayName { get; set; }
public string DepartmentName { get; set; }
public string DivisionName { get; set; }
public string AreaName { get; set; }
public int Extension { get; set; }
public string BuildingName { get; set; }
public string RoomNumber { get; set; }
public string Location { get; set; }
public string Site { get; set; }
public string Switchboard { get; set; }
public string DirectoryAssistant { get; set; }
public string MailboxLocation { get; set; }
public bool ActiveFG { get; set; }
public bool Person { get; set; }
public string LastUpdatedBy { get; set; }
public DateTime LastUpdatedDate { get; set; }
}
@model <whatever the namespace is>.HomeViewModel