我有3个具有多对多连接的实体(表):
public class AccUserRole
{
public long Id { get; set; }
public string RoleName { get; set; }
public List<AccAdGroup> Groups { get; set; }
public List<AccScreen> Screens { get; set; }
}
public class AccAdGroup
{
public long Id { get; set; }
public string AdIdent { get; set; }
public List<AccUserRole> Roles { get; set; }
}
public class AccScreen
{
public long Id { get; set; }
public string ScreenIdent { get; set; }
public List<AccUserRole> Roles { get; set; }
}
我希望获得至少包含一个指定组列表(当前用户组)的所有角色(包括其屏幕和组)。所以我使用了这个查询:
List<AccUserRole> userRoles = (from ur in db.AccUserRoles.Include("Groups").Include("Screens")
from g in ur.Groups
where user.Groups.Contains(g.AdIdent)
select ur).ToList();
它获得了正确的角色,但Groups
和Screens
属性为null。看起来EF在使用Include
和第二from
时遇到问题。
任何有关如何包含属性或重写查询的帮助将不胜感激。
答案 0 :(得分:5)
急切加载
这样做的原因是你只指定了一个包含级别,而你的查询要求在第二级别提供某些内容。
您的附加内容可让您提出ur.Groups
和ur.Screens
。
下一级是from g in ur.Groups
,您没有包含该级别。 (这对您来说可能是意料之外的,因为您已经在查询的第一部分中请求了所有AccUserRoles
。)
要使您的查询运行,您可以在开始时添加另一个.include
,深入两个级别:
from ur in db.AccUserRoles
.Include("Groups")
.Include("Groups.Roles")
.Include("Screens")
如果你需要进入另一个级别,你只需添加另一个包括:
from ur in db.AccUserRoles
.Include("Groups")
.Include("Groups.Roles")
.Include("Groups.Roles.Groups")
.Include("Screens")
...等
如果你有很多级别要嵌套,这可能会变得很麻烦,所以另一种选择是使用延迟加载,正如Praval'Shaun'Tirubeni建议的那样,添加{{1关键字到实体中的集合。
答案 1 :(得分:3)
在ToList()
之前移动包含。
select ur).Include("Groups").Include("Screens").ToList();
子选择可以删除Include
效果。
如果您正在进行热切加载,则不需要virtual
关键字。
通过添加virtual
,您正在使用延迟加载,而不是急切加载。
答案 2 :(得分:1)
尝试将虚拟关键字添加到类属性中,如下所示:
public class AccUserRole
{
public long Id { get; set; }
public string RoleName { get; set; }
public virtual List<AccAdGroup> Groups { get; set; }
public virtual List<AccScreen> Screens { get; set; }
}
public class AccAdGroup
{
public long Id { get; set; }
public string AdIdent { get; set; }
public virtual List<AccUserRole> Roles { get; set; }
}
public class AccScreen
{
public long Id { get; set; }
public string ScreenIdent { get; set; }
public virtual List<AccUserRole> Roles { get; set; }
}