简体   繁体   中英

Entity Framework navigating using navigation properties more than one level

I have Entity model classes as follows

public partial class User
{
    public User()
    {
        this.webpages_Roles = new HashSet<webpages_Roles>();
    }

    public int UserID { get; set; }

    public virtual ICollection<webpages_Roles> webpages_Roles { get; set; }
}

.

public partial class webpages_Roles
{
    public webpages_Roles()
    {
        this.Users = new HashSet<User>();
        this.Roles_X_ApplicationModules = 
                       new HashSet<Roles_X_ApplicationModules>();
    }

    public int RoleId { get; set; }


    public virtual ICollection<User> Users { get; set; }
    public virtual ICollection<Roles_X_ApplicationModules> 
                                   Roles_X_ApplicationModules { get; set; }
}

.

public partial class Roles_X_ApplicationModules
{
    public long ID { get; set; }
    public Nullable<int> ModuleID { get; set; }
    public Nullable<int> RoleID { get; set; }
    public Nullable<bool> ViewPermission { get; set; }

    public virtual ApplicationModule ApplicationModule { get; set; }
    public virtual webpages_Roles webpages_Roles { get; set; }
}

.and

public partial class ApplicationModule
{
    public ApplicationModule()
    {
        this.Roles_X_ApplicationModules = 
                           new HashSet<Roles_X_ApplicationModules>();
    }

    public int ModuleID { get; set; }

    public virtual ICollection<Roles_X_ApplicationModules> 
                                      Roles_X_ApplicationModules { get; set; }
}

you can see User object has a navigation property to webpages_Roles which again has navigation property to Roles_X_ApplicationModules and which in turn navigates to ApplicationModule ..

now I want to get all the ApplicationModule from User..how do I write query using navigation properties..

I tried something like this..

var appModules = user.webpages_Roles.SingleOrDefault()
       .Roles_X_ApplicationModules.Where(z => z.ViewPermission == true)
       .Select(x => x.ApplicationModule);

but problem with this is, it doesn't issue a single query to database. It splits the query to get the webpages_Roles at SingleOrDefault then another query to get the Roles_X_ApplicationModules based on the RoleId and at the end as many queries as Roles_X_ApplicationModules matching the condition to get the ApplicationModule .

How do I write the LINQ query so that a single sql query is issued to database?

You can use Include() to do this. Example:

card = Cards.Include(l => l.DocumentLinks)
            .Include(l => l.Charges.Select(ch => ch.DocumentLinks)
            .SingleOrDefault(c=>c.Id==id);

This is for three linked Entities:

public class Card
{
    public Guid Id{get;set;}
    public virtual ICollection<DocumentLink> DocumentLinks{get;set;}
    public virtual ICollection<Charge> Charges{get;set;}
}

public class Charge
{
    ...
    public virtual ICollection<DocumentLink> DocumentLinks{get;set;}
}

public class DocumentLink
{
    ...
}

try this:

var appModules = from u in user
                 from w in u.webpages_Roles
                 from am in w.Roles_X_ApplicationModules
                 where am.ViewPermission == true
                 select am;

if you want eager loading then you just need to call ToList:

var appModules = (from u in user
                 from w in u.webpages_Roles
                 from am in w.Roles_X_ApplicationModules
                 where am.ViewPermission == true
                 select am).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM