public static IQueryable <T> ThenInclude <T>(this IQueryable <T> source, IncludeExpressionInfo info) { _ = info ?? throw new ArgumentNullException(nameof(info)); _ = info.PreviousPropertyType ?? throw new ArgumentNullException(nameof(info.PreviousPropertyType)); var exp = source.Expression as MethodCallExpression; var arg = exp.Arguments[0] as ConstantExpression; string previousPropertyName; if (arg.Value is string) { previousPropertyName = arg.Value.ToString(); } else { // System.Data.Entity.Core.Objects.Span is an internal class, so here's some reflection to get to the previous property. var propertyInfo = arg.Value.GetType().GetProperty("SpanList", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var spanList = propertyInfo.GetValue(arg.Value); // Get the first item of the span list propertyInfo = propertyInfo.PropertyType.GetProperty("Item"); var spanPath = propertyInfo.GetValue(spanList, new object[] { 0 }); var fieldInfo = spanPath.GetType().GetField("Navigations", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var navigations = fieldInfo.GetValue(spanPath) as List <string>; previousPropertyName = string.Join(".", navigations); } var propertyName = GetPropertyName(info.LambdaExpression); return(QueryableExtensions.Include(source, $"{previousPropertyName}.{propertyName}")); }
public static IQueryable <T> Include <T>(this IQueryable <T> source, IncludeExpressionInfo info) { _ = info ?? throw new ArgumentNullException(nameof(info)); var propertyName = GetPropertyName(info.LambdaExpression); return(QueryableExtensions.Include(source, propertyName)); }
/// <summary> /// Include /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="specificationBuilder"></param> /// <param name="includeExpression"></param> /// <returns></returns> public static IIncludableSpecificationBuilder <T, TProperty> Include <T, TProperty>(this ISpecificationBuilder <T> specificationBuilder, Expression <Func <T, TProperty> > includeExpression) { var info = new IncludeExpressionInfo(includeExpression, typeof(T), typeof(TProperty)); ((List <IncludeExpressionInfo>)specificationBuilder.Specification.IncludeExpressions).Add(info); var includeBuilder = new IncludableSpecificationBuilder <T, TProperty>(specificationBuilder.Specification); return(includeBuilder); }
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <typeparam name="TPreviousProperty"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="previousBuilder"></param> /// <param name="thenIncludeExpression"></param> /// <returns></returns> public static IIncludableSpecificationBuilder <TEntity, TProperty> ThenInclude <TEntity, TPreviousProperty, TProperty>( this IIncludableSpecificationBuilder <TEntity, IEnumerable <TPreviousProperty> > previousBuilder, Expression <Func <TPreviousProperty, TProperty> > thenIncludeExpression) where TEntity : class { var info = new IncludeExpressionInfo(thenIncludeExpression, typeof(TEntity), typeof(TProperty), typeof(TPreviousProperty)); ((List <IncludeExpressionInfo>)previousBuilder.Specification.IncludeExpressions).Add(info); var includeBuilder = new IncludableSpecificationBuilder <TEntity, TProperty>(previousBuilder.Specification); return(includeBuilder); }
/// <summary> /// 加载导航属性 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="info"></param> /// <returns></returns> public static IQueryable <T> Include <T>(this IQueryable <T> source, IncludeExpressionInfo info) { _ = info ?? throw new ArgumentNullException(nameof(info)); var queryExpr = Expression.Call( typeof(EntityFrameworkQueryableExtensions), "Include", new Type[] { info.EntityType, info.PropertyType }, source.Expression, info.LambdaExpression ); return(source.Provider.CreateQuery <T>(queryExpr)); }