[英]Entity Framework returns null for Include properties
I got 3 entities(tables) that have many to many connections: 我有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; }
}
I wanted to get all Roles(including their screens and groups) that has at least one of specified list of groups(the groups of the current user). 我想获得至少有一个指定的组列表(当前用户的组)的所有角色(包括他们的屏幕和组)。 So I used this query:
所以我使用了这个查询:
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();
It gets the right roles, but the Groups
and Screens
properties are null. 它获得了正确的角色,但
Groups
和Screens
属性为null。 Looks like EF has a problem with using Include
and second from
. 看起来像EF具有:使用问题
Include
和第二from
。 Any help on how to include the properties or rewrite the query will be appreciated. 任何有关如何包含属性或重写查询的帮助将不胜感激。
Eager Loading 渴望加载
The reason for this is that you have specified only one level of include, while your query is asking for something on the second level. 这样做的原因是您只指定了一个包含级别,而您的查询是在第二级别请求某些内容。
Your include lets you ask for ur.Groups
and ur.Screens
. 您的include允许您询问
ur.Groups
和ur.Screens
。 The next level is from g in ur.Groups
, and you haven't included that level. 下一个级别
from g in ur.Groups
,并且您没有包含该级别。 (This is probably unexpected for you, since you already have asked for all AccUserRoles
in the first part of the query.) (这对您来说可能是意料之外的,因为您已经在查询的第一部分中询问了所有
AccUserRoles
。)
To make your query run, you could add another .include
at the start, going two levels deep: 要使您的查询运行,您可以在开始时添加另一个
.include
,深入两个级别:
from ur in db.AccUserRoles
.Include("Groups")
.Include("Groups.Roles")
.Include("Screens")
If you need to go yet another level, you'd just add yet another include: 如果你需要进入另一个级别,你只需添加另一个包括:
from ur in db.AccUserRoles
.Include("Groups")
.Include("Groups.Roles")
.Include("Groups.Roles.Groups")
.Include("Screens")
...etc. ...等等。
This might become cumbersome if you have a whole lot of levels to nest, so an alternative would be to use Lazy Loading instead, as Praval 'Shaun' Tirubeni suggests, by adding the virtual
keyword to the collections in your entities. 如果你有很多级别要嵌套,这可能会变得很麻烦,所以另一种方法是使用延迟加载 ,正如Praval的Shaun'Tirubeni建议的那样,通过将
virtual
关键字添加到实体中的集合。
Move the include before ToList()
. 在
ToList()
之前移动include。
select ur).Include("Groups").Include("Screens").ToList();
The subselect can remove the Include
effect. 子选择可以删除
Include
效果。
If you are doing eager loading, the virtual
keyword is not needed. 如果您正在进行急切加载,则不需要
virtual
关键字。 By adding virtual
, you are using lazy loading, not eager loading. 通过添加
virtual
,您使用延迟加载,而不是急切加载。
Try adding the virtual key word to your class properties like so: 尝试将虚拟关键字添加到类属性中,如下所示:
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; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.