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.
source to share
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; }
}
source to share
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.
source to share