Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicit Loading nested related models in Entity Framework

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();
like image 682
Usama Avatar asked Apr 22 '18 16:04

Usama


People also ask

What are different types of loading available to load related entities in EF?

Entity Framework supports three ways to load related data - eager loading, lazy loading and explicit loading.

How do I load related entities in Entity Framework Core?

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.

What is the difference between ef6 and EF core?

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.

How do I enable eager loading in Entity Framework?

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.


1 Answers

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();
like image 127
Ivan Stoev Avatar answered Nov 10 '22 07:11

Ivan Stoev