Ho alcune entità Entity Framework 7 (Core):
public class Person {
public virtual Address Address { get; set; }
public virtual ICollection<Hobby> Hobbies { get; set; }
}
public class Address {
public String Street { get; set; }
public virtual Country Country { get; set; }
}
E ho un array di stringhe come segue:
String[] entities = new String[] { "Hobbies", "Address.Country" }
Dato questo array di stringhe ho ottenuto:
context.Persons
.Include(x => x.Hobbies)
.Include(x => x.Address).ThenInclude(x => x.Country);
In EF6 potrei fare qualcosa come:
context.Persons.Include(entities[0]).Include(entities[1]);
Ma in EF7 Include non consente le stringhe. Ho creato il dizionario:
private readonly Dictionary<String, LambdaExpression> _properties = new Dictionary<String, LambdaExpression>();
Quale avrebbe qualcosa di simile:
x => x.Hobbies is for "Hobbies"
x => x.Address.Country is for "Address.Country"
E ho l'estensione:
public static IQueryable<T> Include<T>(this IQueryable<T> source, Dictionary<String, LambdaExpression> properties) {
}
Dove devo dare il dizionario, applica quanto segue:
Per "x => x.Hobbies" basta fare:
source.Include(x => x.Hobbies);
Se l'espressione è qualcosa come "x => x.Address.Country" aggiungi:
source.Include(x => x.Address).ThenInclude(x => x.Country);
Può essere fatto?
Non sono sicuro di ThenInclude()
e EF 7, ma puoi fare qualcosa di simile nei tuoi repository (testato con EF 6):
public MyEntity GetMyEntity_EagerlyLoad(DbContext context, int id, params Expression<Func<MyEntity, object>>[] propertiesToLoad)
{
var q = context.MyEntities.Where(m => m.ID == id);
foreach (var prop in propertiesToLoad)
q = q.Include(prop);
return q.SingleOrDefault();
}
Puoi quindi chiamarlo così:
repo.GetMyEntity_EagerlyLoad(context, id, m => m.Property1, m => m.Property2, m => m.Property1.NestedProperty)
EDIT : C'è anche il modo alternativo per fare il caricamento ansioso con EF utilizzando la proiezione. Potresti fare un metodo di repository generico come questo:
public MyEntity GetMyEntity_EagerlyLoad<T>(DbContext context, int id, Expression<Func<MyEntity, T>> loadingProjection, Func<T, MyEntity> resultProjection)
{
var q = context.MyEntities.Where(m => m.ID == id);
return q.Select(loadingProjection).AsEnumerable().Select(resultProjection).SingleOrDefault();
}
E poi chiamalo con le proprietà che vuoi caricare e l'entità che vuoi che il metodo restituisca:
repo.GetMyEntity_EagerlyLoad(context, id, m => new { myEntity = m, m.Property1, m.Property2, m.Property1.NestedProperty }, m => m.myEntity)