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

时间:2014-09-10 11:18:25

标签: c# sql .net entity-framework

我有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();

它获得了正确的角色,但GroupsScreens属性为null。看起来EF在使用Include和第二from时遇到问题。 任何有关如何包含属性或重写查询的帮助将不胜感激。

3 个答案:

答案 0 :(得分:5)

急切加载

这样做的原因是你只指定了一个包含级别,而你的查询要求在第二级别提供某些内容。

您的附加内容可让您提出ur.Groupsur.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; }
}