Su un'API ho bisogno di includere dinamico ma EF Core non supporta l'inclusione basata su stringhe.È possibile creare un'alternativa basata su stringa basata su Entity Framework Core?
A causa di questo ho creato un mapper che mappa le stringhe di lambda espressioni aggiunti a un elenco come:
List<List<Expression>> expressions = new List<List<Expression>>();
considerare i seguenti tipi specifici:
public class EFContext {
public DbSet<P1> P1s { get; set; }
public DbSet<P1> P2s { get; set; }
public DbSet<P1> P3s { get; set; }
}
public class P1 {
public P2 P2 { get; set; }
public P3 P3 { get; set; }
}
public class P2 {
public P3 P3 { get; set; }
}
public class P3 { }
includere e ThenInclude sono normalmente utilizzati come segue:
EFContext efcontext = new EFContext();
IQueryable<P1> result = efcontext.P1s.Include(p1 => p1.P2).ThenInclude(p2 => p2.P3).Include(p1 => p1.P3);
Possono essere utilizzati anche i seguenti modo:
Expression<Func<P1, P2>> p1p2 = p1 => p1.P2;
Expression<Func<P1, P3>> p1p3 = p1 => p1.P3;
Expression<Func<P2, P3>> p2p3 = p2 => p2.P3;
List<List<Expression>> expressions = new List<List<Expression>> {
new List<Expression> { p1p2, p1p3 },
new List<Expression> { p2p3 }
};
EFContext efcontext = new EFContext();
IIncludableQueryable<P1, P2> q1 = EntityFrameworkQueryableExtensions.Include(efcontext.P1s, p1p2);
IIncludableQueryable<P1, P3> q2 = EntityFrameworkQueryableExtensions.ThenInclude(q1, p2p3);
IIncludableQueryable<P1, P3> q3 = EntityFrameworkQueryableExtensions.Include(q2, p1p3);
result = q3.AsQueryable();
Il problema è il mio metodo riceve un elenco di elenco di espressioni e ho solo il tipo di base a T:
public static class IncludeExtensions<T> {
public static IQueryable<T> IncludeAll(this IQueryable<T> collection, List<List<Expression>> expressions) {
MethodInfo include = typeof(EntityFrameworkQueryableExtensions).GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.Include)).Single(mi => mi.GetParameters().Any(pi => pi.Name == "navigationPropertyPath"));
MethodInfo includeAfterCollection = typeof(EntityFrameworkQueryableExtensions).GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)).Single(mi => !mi.GetParameters()[0].ParameterType.GenericTypeArguments[1].IsGenericParameter);
MethodInfo includeAfterReference = typeof(EntityFrameworkQueryableExtensions).GetTypeInfo().GetDeclaredMethods(nameof(EntityFrameworkQueryableExtensions.ThenInclude)).Single(mi => mi.GetParameters()[0].ParameterType.GenericTypeArguments[1].IsGenericParameter);
foreach (List<Expression> path in expressions) {
Boolean start = true;
foreach (Expression expression in path) {
if (start) {
MethodInfo method = include.MakeGenericMethod(typeof(T), ((LambdaExpression)expression).ReturnType);
IIncludableQueryable<T,?> result = method.Invoke(null, new Object[] { collection, expression });
start = false;
} else {
MethodInfo method = includeAfterReference.MakeGenericMethod(typeof(T), typeof(?), ((LambdaExpression)expression).ReturnType);
IIncludableQueryable <T,?> result = method.Invoke(null, new Object[] { collection, expression });
}
}
}
return collection; // (to be replaced by final as Queryable)
}
}
Il problema principale è stato risolvendo i tipi corretti per ogni Includi e poiIncludere i passaggi e anche quale ThenInclude utilizzare ...
E 'anche possibile con l'attuale core EF7? Qualcuno ha trovato una soluzione per l'inclusione dinamica?
I Include e ThenIncludeAfterReference e ThenIncludeAfterCollection metodi sono parte di EntityFrameworkQueryableExtensions classe EntityFramework Github's repository.
Potete fornire più contesto? Come si costruiscono questi elenchi di espressioni, perché sono elenchi di elenchi, sono sempre singoli accessor di proprietà lambda ecc. O meglio alcuni esempi di stringhe che si stanno elaborando, come "P2.P3" e "P3" o? –