简体   繁体   中英

How to eagerly load all referenced entities dynamically in Entity Framework

  • EF 6
  • I have the following POCO's

_

public class StructureEntity : EmEntityBase
{
    [ForeignKey("ParentStructureId")]
    public virtual StructureEntity ParentStructure { get; set; }

    public long? ParentStructureId { get; set; }

    [ForeignKey("SiteId")]
    public virtual SiteEntity Site { get; set; }

    [Required(ErrorMessage = "Required.")]
    public long SiteId { get; set; }

    [Required(ErrorMessage = "Required.")]
    public string Name { get; set; }
}

public class SiteEntity : EmEntityBase
{
    [ForeignKey("ParentSiteId")]
    public virtual SiteEntity ParentSite { get; set; }

    public long? ParentSiteId { get; set; }

    [Required(ErrorMessage = "Required.")]
    public long ClientId { get; set; }

    [ForeignKey("ClientId")]
    public ClientEntity Client { get; set; }

    [Required(ErrorMessage = "Required.")]
    public string Name { get; set; }
}

public class ClientEntity : EmEntityBase
{
    public long? ParentClientId { get; set; }

    [ForeignKey("ParentClientId")]
    public virtual ClientEntity ParentClient { get; set; }

    public string Name { get; set; }
}

Now when I want to eagerly load all the referenced entities. To do this I have:

    public IQueryable<StructureDivisionEntity> GetAllWithInclude()
   {
   return GetAll()
         .Include(e => e.Structure)
         .Include(e => e.ParentStructureDivision.Structure)
         .Include(e => e.Structure.Site.Client);
   }

I was wondering if there was a dynamic way to do this without explicitly having to do the .Include(Structure) etc. Something along the lines of:

MyEntity.IncludeAllReferenced() where IncludeAllReferenced used reflection or similair to traverse MyEntity and do all the includes?

UPDATE: Alternative Approach To Querying Complex Graphs

You can't do that, but you can make an extensionmethod to get all. This might be a crazy idea, but you could make a generic extension-method to handle all your types, to make the code more clean.

Example, (one could extend this with factory-pattern if necessary):

public static IQueryable<T> IncludeAll<T>(this IQueryable<T> query)
{
   if (typeof(T) == typeof(StructureDivisionEntity))
   {
       return GetAllWithInclude(query);
   }
   throw new NotImplementedException("IncludeAll not implemented for type {0}",typeof(T).FullName);
}

private static IQueryable<StructureDivisionEntity> GetAllWithInclude<StructureDivisionEntity> (IQueryable<StructureDivisionEntity> query) 
{
   return query.Include(e => e.Structure)
               .Include(e => e.ParentStructureDivision.Structure)
               .Include(e => e.Structure.Site.Client);
}

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