В API мне нужно динамическое включение, но EF Core не поддерживает String.Можно ли создать альтернативный вариант String в Entity Framework Core?
Из-за этого я создал картографа, который отображает Струны для лямбда-выражений, добавленных в список как:
List<List<Expression>> expressions = new List<List<Expression>>();
Рассмотрим следующие конкретные типы:
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 { }
Включать и ThenInclude, как правило, используются в качестве следует:
EFContext efcontext = new EFContext();
IQueryable<P1> result = efcontext.P1s.Include(p1 => p1.P2).ThenInclude(p2 => p2.P3).Include(p1 => p1.P3);
Их также можно использовать путь:
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();
Проблема мой метод получает список Список выражений, и я только базовый тип в 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)
}
}
Основной проблемой было разрешения правильных типов для каждого Включать и ThenInclude, а также, что ThenInclude для использования ...
Возможно ли это с нынешним ядром EF7? Кто-нибудь нашел решение для динамического включения?
В Include и ThenIncludeAfterReference и ThenIncludeAfterCollection методы являются частью класса EntityFrameworkQueryableExtensions в EntityFramework Github's хранилище.
Можете ли вы предоставить больше контекста? Как вы строите эти списки выражений, почему они являются списком списков, всегда ли они являются одиночными атрибутами доступа к ресурсам lambdas и т. Д. Или лучше какой-то образец строк, которые вы обрабатываете, например «P2.P3» и «P3» или? –