I'm working on an ASP.NET MVC5 project using EF6. I have 3 models: user, role and permission.
The relation between user and role is many to many. The relation between role and permission is many to many.
LazyLoadingEnabled is disabled in the database context.
public class Permission
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
public class Role
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Permission> Permissions { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class User
{
public int ID { get; set; }
public string Username { get; set; }
public string DisplayName { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
public class TaskManagerDB : DbContext
{
public TaskManagerDB() : base()
{
Configuration.LazyLoadingEnabled = false;
}
public DbSet<Role> Roles { get; set; }
public DbSet<Permission> Permissions { get; set; }
public DbSet<User> Users { get; set; }
}
At an earlier point, I fetch a given user:
User user = db.Users.Find(1);
Now: since I already have the model, how can I load the user roles with their permissions?
I have tried:
db.Entry(user).Collection(x => x.Roles).Query().Include(y => y.Permissions).Load();
But it's not working - user.Roles
is still null
.
The following solution is not acceptable because I already have the user Model:
User user = db.Users.Include("Roles.Permissions").Where(x => x.ID == 1).FirstOrDefault();
Entity Framework supports three ways to load related data - eager loading, lazy loading and explicit loading.
Entity Framework Core allows you to use the navigation properties in your model to load related entities. There are three common O/RM patterns used to load related data. Eager loading means that the related data is loaded from the database as part of the initial query.
EF 6 is a stable and mature ORM while EF Core is relatively new. Microsoft rebuilt EF Core from the ground up and removed many of the internal dependencies and providers that EF 6 had (like SQLClient). In the long run, that will make EF Core much more extensible and lighter weight.
Entity Framework : A Comprehensive Course Eager loading is the process whereby a query for one type of entity also loads related entities as part of the query. Eager loading is achieved by the use of the Include method. It means that requesting related data be returned along with query results from the database.
What you have tried
db.Entry(user).Collection(x => x.Roles).Query()
.Include(y => y.Permissions)
.Load();
is indeed the intended way. And it works for everything else except the many-to-many relationship with implicit junction table, which is the case here.
I don't know if it's a bug or "by design", but the solution is to Include
the other (calling) end of the relationship, e.g.
db.Entry(user).Collection(x => x.Roles).Query()
.Include(y => y.Users) // <--
.Include(y => y.Permissions)
.Load();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With