为什么在链接到实体查询中可以看到多对多,直到我将其投影到SelectItemList?

时间:2018-04-19 22:14:06

标签: asp.net-core-mvc entity-framework-core asp.net-core-2.0

我有这个问题。

   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。

拳头()让我在结果中找到了办公室:

enter image description here

这是现在的查询

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

1 个答案:

答案 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则不显示办公室或空()。