patterncsharpModerate
DbSet<T> IncludeAll method
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.
If I want to include all navigation models I'll have to include all those models.
My solution
I built an extension method to remove this from my controller code.
There are a few problems with this:
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()andIncludedFind()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;
I hope this answers your question.
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.