Entity Framework returns null for Include properties

I have 3 objects (tables) that have many different connections:

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 have at least one of the specified groups (current user's groups). 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 correct roles, but the properties Groups

and Screens

are null. It looks like EF has problems using the Include

second too from

. Any help on including properties or rewriting the query would be appreciated.

+3


source to share


3 answers


Try adding virtual keyword to your class properties like this:



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; }
}

      

+1


source


Big load

The reason for this is that you only specified one level of include, while your request asks for something at the second level.

In your inclusion, you can request ur.Groups

and ur.Screens

. The next level from g in ur.Groups

and you have not included this level. (This is probably unexpected for you, since you already requested everything AccUserRolse

in the first part of the request.)

To run your query, you can add another one .include

at the beginning, going up two levels:

from ur in db.AccUserRoles
             .Include("Groups")
             .Include("Groups.Roles")
             .Include("Screens")

      



If you need to complete one more level, you simply add another option:

from ur in db.AccUserRoles
             .Include("Groups")
             .Include("Groups.Roles")
             .Include("Groups.Roles.Groups")
             .Include("Screens")

      

... etc..

This can get cumbersome if you have many levels for the nest, so an alternative would be to use Lazy Loading instead, as Praval 'Shaun' Tirubeni suggests, adding a keyword virtual

to collections in your entities.

+3


source


Move the pointer in front ToList()

.

select ur).Include("Groups").Include("Screens").ToList();

      

The subtitle can remove the effect Include

.

If you are downloading, the keyword is virtual

not required. By adding virtual

, you are using lazy loading, not loading.

+2


source







All Articles