HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

DbSet<T> IncludeAll method

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
includealldbsetmethod

Problem

The Problem

As an ASP.NET MVC4 developper, I'm using Entity Framework a lot. Considering performance I often use lazy loading for my models.

public class Result {
    public int Id { get; set; }
    public decimal Grade { get; set; }
    public virtual Skill Skill { get; set; }
    public int SkillId { get; set; }
    public virtual Player Player { get; set; }
    public int PlayerId { get; set; }
    public virtual Category { get; set; }
    public int CategoryId { get; set; }
}


If I want to include all navigation models I'll have to include all those models.

public ActionResult Details(int id = 0)
{
    Result result = db.Results
                      .Include(r => r.Skill)
                      .Include(r => r.Player)
                      .Include(r => r.Category)
                      .SingleOrDefault(r => r.Id == id);
    //some viewmodel mapping
    return View(viewmodel);
}


My solution

I built an extension method to remove this from my controller code.

public static class IncludeExtensions
{
    public static IQueryable IncludeAll(this IQueryable results)
    {
        return results.Include(r => r.Skill)
                      .Include(r => r.Player)
                      .Include(r => r.Category);
    }

    public static Result IncludedFind(this IQueryable results, int id)
    {
        return results.IncludeAll().SingleOrDefault(r => r.Id == id);
    }
}

public ActionResult Details(int id = 0)
{
    Result result = db.Results.IncludedFind(id);
    //some viewmodel mapping
    return View(viewmodel);
}


There are a few problems with this:

  • I can't create an abstract extension class to force IncludeAll() and IncludedFind() method.



  • I still have to update the extension method if my models change.



  • I'll have a proliferation of extension methods/classes.



  • Isn't there an IncludeAll() like method available for Entity Framework?



  • Is there something like this on NuGet?



  • It just feels wrong...

Solution

A simple option would be to use reflection to check for properties that are virtual and has the Id-suffix. This is where I came up with, working for me;

public static IQueryable IncludeAll(this IQueryable queryable) where T : class
{
   var type = typeof (T);
   var properties = type.GetProperties();
   foreach (var property in properties)
   {
       var isVirtual = property.GetGetMethod().IsVirtual;
       if (isVirtual && properties.FirstOrDefault(c => c.Name == property.Name + "Id") != null)
       {
           queryable = queryable.Include(property.Name);
       }
   }
   return queryable;
}


I hope this answers your question.

Code Snippets

public static IQueryable<T> IncludeAll<T>(this IQueryable<T> queryable) where T : class
{
   var type = typeof (T);
   var properties = type.GetProperties();
   foreach (var property in properties)
   {
       var isVirtual = property.GetGetMethod().IsVirtual;
       if (isVirtual && properties.FirstOrDefault(c => c.Name == property.Name + "Id") != null)
       {
           queryable = queryable.Include(property.Name);
       }
   }
   return queryable;
}

Context

StackExchange Code Review Q#30839, answer score: 11

Revisions (0)

No revisions yet.