我有这个问题。
IQueryable<Staff> aolStaff =
_userRepo.Users
.Include(u => u.StaffOffices).ThenInclude(so => so.Office)
.Include(u => u.Positions).ThenInclude(p => p.Role)
.Where(u => u.Positions.Any(p => p.Role.RoleCd == "PO_ALO"));
UsersRepo此处返回一个IQueryable of Staff对象。
Staff对象有一个StaffOffices和Postions列表。这些都是Entity Framework Core 2的多对数桥接表。
StaffOffice对象有一个StaffId和一个OfficeId以及一个导航属性 一个Staff对象和一个Office对象。
Postion对象有一个StaffId和一个RoleId以及一个导航属性 一个Staff对象和一个Role对象。
这是StaffOffice POCO:
[Table("staff_office")]
public class StaffOffice
{
[Column("staff_office_staff_id")]
public short ID { get; set; }
public Staff Staff { get; set; }
[Column("staff_office_office_id")]
public short OfficeID { get; set; }
public Office Office { get; set; }
}
这是职位POCO:
[Table("position")]
public class Position
{
[Column("position_staff_id")]
public short ID { get; set; }
public Staff Staff { get; set; }
[Column("position_role_id")]
public short RoleID { get; set; }
public Role Role { get; set; }
}
当我运行此查询时,我可以设置断点并查看结果。 结果中的工作人员有一个StaffOffice集合,办公室在那里,我可以到办公室名称。
但我需要将其投射到SelectItemList。
因此,我尝试将查询结果的类型从IQueryable of Staff更改为SelectListItem的IQueryable,并将其添加到查询的末尾。
.Select(u =>
new SelectListItem
{
Text = $"{u.FullName}" + $"{u.StaffOffices[0].Office.OfficeNm}",
Value = u.StaffID.ToString()
});
我真正需要的每个SelectListItem的文本是全名和逗号分隔的办公室列表,如下所示:
Sam Miller(OFCO,PGA,OLM)
所以这是整个查询:
IQueryable<SelectListItem> aolStaff =
_userRepo.Users
.Include(u => u.StaffOffices).ThenInclude(so => so.Office)
.Include(u => u.Positions).ThenInclude(p => p.Role)
.Where(u => u.Positions.Any(p => p.Role.RoleCd == "PO_ALO"))
.Select(u =>
new SelectListItem
{
Text = $"{u.FullName}" + $"{u.StaffOffices[0].Office.OfficeNm}",
Value = u.StaffID.ToString()
});
最终我需要上面为文本编写的格式,但此时我只是想在StaffOffice Collection的Office的OfficeName的第一个元素中获取第一个Office名称。
但是当我点击断点并扩展结果时,我得到了这个异常: 对象引用未设置为对象的实例。
我知道这不是很多,但我一整天都在看这个,我只是不知道该怎么做。
如果我运行此操作,我会在查询中为每个员工获取一个Office名称:
foreach(Staff staff in aolStaff)
{
string nm = staff.StaffOffices[0].Office.OfficeNm;
System.Diagnostics.Debug.Write("nm: " + nm + "\n");
}
如何将此查询提供给下一步? 我做错了什么。
为什么无论我如何尝试将这些结果导入SelectListItem,它似乎都会想到(我认为StaffOffice集合)是空的?
更新
感谢MickaëlDerriey。
拳头()让我在结果中找到了办公室:
这是现在的查询
IQueryable<SelectListItem> aolStaff =
_userRepo.Users
.Include(u => u.StaffOffices).ThenInclude(so => so.Office)
.Include(u => u.Positions).ThenInclude(p => p.Role)
.Where(u => u.Positions.Any(p => p.Role.RoleCd == "PO_ALO"))
.Select(u =>
new SelectListItem
{
Text = $"{u.FullName}" + $"{u.StaffOffices.FirstOrDefault().Office.OfficeNm}",
Value = u.StaffID.ToString()
});
现在我需要接受这一部分:
$"{u.StaffOffices.FirstOrDefault().Office.OfficeNm}"
并执行以下操作:
$"({u.StaffOffices.Join(','))"
制作以逗号分隔的列表。 如果StaffOffices计数为0,那么不显示空()会更好。
更新3
不 - 我把它拿回来。它不起作用。它只显示全名文字。不是办公室信息。所以FirstOrDefault()返回null。
尝试使QueryResult IQueryable并将其forloop转换为IQueryable
答案 0 :(得分:0)
实际上它正在运作。我只是没有在全名右边看到OM这样的办公室,因为我忘记了中间的空间。
以下是最终代码:
IQueryable<Staff> aolStaffMembers =
_userRepo.Users
.Include(u => u.StaffOffices).ThenInclude(so => so.Office)
.Include(u => u.Positions).ThenInclude(p => p.Role)
.Where(u => u.Positions.Any(p => p.Role.RoleCd == "PO_ALO"));
List<SelectListItem> aolStaffList = new List<SelectListItem>();
foreach (Staff staff in aolStaffMembers)
{
aolStaffList.Add(
new SelectListItem
{
Text = $"{staff.FullName}" + $" ({string.Join(", ", from o in staff.StaffOffices select o.Office.OfficeOrganizationCd)})",
Value = staff.StaffID.ToString()
}
);
}
这就是我需要获得逗号分隔列表的内容:
string.Join(", ", from o in staff.StaffOffices select o.Office.OfficeOrganizationCd)})"
我仍然想检查一下,如果StaffOffices.Count()== 0则不显示办公室或空()。