简体   繁体   English

实体框架为包含属性返回null

[英]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. 它获得了正确的角色,但GroupsScreens属性为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.Groupsur.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM