public void Every_eventId_has_a_logger_method_and_logs_when_level_enabled()
        {
            var entityType            = new EntityType(typeof(object), new Model(new ConventionSet()), ConfigurationSource.Convention);
            var property              = new Property("A", typeof(int), null, null, entityType, ConfigurationSource.Convention, ConfigurationSource.Convention);
            var queryModel            = new QueryModel(new MainFromClause("A", typeof(object), Expression.Constant("A")), new SelectClause(Expression.Constant("A")));
            var includeResultOperator = new IncludeResultOperator(new[] { "Foo" }, Expression.Constant("A"));
            var options = new DbContextOptionsBuilder().UseInMemoryDatabase("D").Options;

            var fakeFactories = new Dictionary <Type, Func <object> >
            {
                { typeof(Type), () => typeof(object) },
                { typeof(DbContext), () => new DbContext(options) },
                { typeof(DbContextOptions), () => options },
                { typeof(QueryModel), () => queryModel },
                { typeof(string), () => "Fake" },
                { typeof(IExpressionPrinter), () => new ExpressionPrinter() },
                { typeof(Expression), () => Expression.Constant("A") },
                { typeof(IEntityType), () => entityType },
                { typeof(IKey), () => new Key(new[] { property }, ConfigurationSource.Convention) },
                { typeof(IPropertyBase), () => property },
                { typeof(IServiceProvider), () => new FakeServiceProvider() },
                { typeof(ICollection <IServiceProvider>), () => new List <IServiceProvider>() },
                { typeof(IReadOnlyCollection <IPropertyBase>), () => new[] { property } },
                { typeof(IncludeResultOperator), () => includeResultOperator },
                { typeof(IReadOnlyList <System.Exception>), () => new[] { new Exception() } }
            };

            InMemoryTestHelpers.Instance.TestEventLogging(typeof(CoreEventId), typeof(CoreLoggerExtensions), fakeFactories);
        }
        public void Every_eventId_has_a_logger_method_and_logs_when_level_enabled()
        {
            var propertyInfo = typeof(DateTime).GetTypeInfo().GetDeclaredProperty(nameof(DateTime.Now));
            var entityType   = new EntityType(typeof(object), new Model(new ConventionSet()), ConfigurationSource.Convention);
            var property     = new Property(
                "A", typeof(int), propertyInfo, null, entityType, ConfigurationSource.Convention, ConfigurationSource.Convention);
            var otherEntityType = new EntityType(typeof(object), entityType.Model, ConfigurationSource.Convention);
            var otherProperty   = otherEntityType.AddProperty("A", typeof(int), ConfigurationSource.Convention, ConfigurationSource.Convention);
            var otherKey        = otherEntityType.AddKey(otherProperty, ConfigurationSource.Convention);
            var foreignKey      = new ForeignKey(new[] { property }, otherKey, entityType, otherEntityType, ConfigurationSource.Convention);
            var navigation      = new Navigation("N", propertyInfo, null, foreignKey);
            var queryModel      = new QueryModel(
                new MainFromClause("A", typeof(object), Expression.Constant("A")), new SelectClause(Expression.Constant("A")));
            var includeResultOperator = new IncludeResultOperator(new[] { "Foo" }, Expression.Constant("A"));
            var options = new DbContextOptionsBuilder()
                          .UseInternalServiceProvider(InMemoryFixture.DefaultServiceProvider)
                          .UseInMemoryDatabase("D").Options;

            var fakeFactories = new Dictionary <Type, Func <object> >
            {
                { typeof(Type), () => typeof(object) },
                { typeof(DbContext), () => new DbContext(options) },
                { typeof(DbContextOptions), () => options },
                { typeof(QueryModel), () => queryModel },
                { typeof(string), () => "Fake" },
                { typeof(IExpressionPrinter), () => new ExpressionPrinter() },
                { typeof(Expression), () => Expression.Constant("A") },
                { typeof(IEntityType), () => entityType },
                { typeof(IKey), () => new Key(new[] { property }, ConfigurationSource.Convention) },
                { typeof(IPropertyBase), () => property },
                { typeof(IServiceProvider), () => new FakeServiceProvider() },
                { typeof(ICollection <IServiceProvider>), () => new List <IServiceProvider>() },
                { typeof(IReadOnlyList <IPropertyBase>), () => new[] { property } },
                { typeof(IEnumerable <Tuple <MemberInfo, Type> >), () => new[] { new Tuple <MemberInfo, Type>(propertyInfo, typeof(object)) } },
                { typeof(MemberInfo), () => propertyInfo },
                { typeof(IncludeResultOperator), () => includeResultOperator },
                { typeof(IReadOnlyList <Exception>), () => new[] { new Exception() } },
                { typeof(IProperty), () => property },
                { typeof(INavigation), () => navigation },
                { typeof(IForeignKey), () => foreignKey },
                { typeof(InternalEntityEntry), () => new FakeInternalEntityEntry(entityType) },
                { typeof(ISet <object>), () => new HashSet <object>() },
                {
                    typeof(IList <IDictionary <string, string> >),
                    () => new List <IDictionary <string, string> > {
                        new Dictionary <string, string> {
                            { "A", "B" }
                        }
                    }
                },
                { typeof(IDictionary <string, string>), () => new Dictionary <string, string>() }
            };

            TestEventLogging(
                typeof(CoreEventId),
                typeof(CoreLoggerExtensions),
                typeof(LoggingDefinitions),
                fakeFactories);
        }
Beispiel #3
0
 /// <summary>
 ///     Constructs the event payload.
 /// </summary>
 /// <param name="eventDefinition"> The event definition. </param>
 /// <param name="messageGenerator"> A delegate that generates a log message for this event. </param>
 /// <param name="includeResultOperator"> The <see cref="IncludeResultOperator"/>. </param>
 public IncludeEventData(
     [NotNull] EventDefinitionBase eventDefinition,
     [NotNull] Func <EventDefinitionBase, EventData, string> messageGenerator,
     [NotNull] IncludeResultOperator includeResultOperator)
     : base(eventDefinition, messageGenerator)
 {
     IncludeResultOperator = includeResultOperator;
 }
 public IncludeSpecification(
     IncludeResultOperator includeResultOperator,
     QuerySourceReferenceExpression querySourceReferenceExpression,
     INavigation[] navigationPath)
 {
     IncludeResultOperator          = includeResultOperator;
     QuerySourceReferenceExpression = querySourceReferenceExpression;
     NavigationPath = navigationPath;
 }
Beispiel #5
0
        private bool TryPopulateIncludeLoadTree(
            IncludeResultOperator includeResultOperator,
            IncludeLoadTree includeLoadTree,
            bool shouldThrow)
        {
            if (includeResultOperator.NavigationPaths != null)
            {
                foreach (var navigationPath in includeResultOperator.NavigationPaths)
                {
                    includeLoadTree.AddLoadPath(navigationPath);
                }

                return(true);
            }

            IEntityType entityType = null;

            if (includeResultOperator.PathFromQuerySource is QuerySourceReferenceExpression qsre)
            {
                entityType = _queryCompilationContext.FindEntityType(qsre.ReferencedQuerySource);
            }

            if (entityType == null)
            {
                entityType = _queryCompilationContext.Model.FindEntityType(includeResultOperator.PathFromQuerySource.Type);

                if (entityType == null)
                {
                    var pathFromSource = MemberAccessBindingExpressionVisitor.GetPropertyPath(
                        includeResultOperator.PathFromQuerySource, _queryCompilationContext, out qsre);

                    if (pathFromSource.Count > 0 &&
                        pathFromSource[pathFromSource.Count - 1] is INavigation navigation)
                    {
                        entityType = navigation.GetTargetType();
                    }
                }
            }

            if (entityType == null)
            {
                if (shouldThrow)
                {
                    throw new InvalidOperationException(
                              CoreStrings.IncludeNotSpecifiedDirectlyOnEntityType(
                                  includeResultOperator.ToString(),
                                  includeResultOperator.NavigationPropertyPaths.FirstOrDefault()));
                }

                return(false);
            }

            return(WalkNavigations(entityType, includeResultOperator.NavigationPropertyPaths, includeLoadTree, shouldThrow));
        }
        protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
        {
            var navigationPropertyPath
                = Source.Resolve(
                    _navigationPropertyPathLambda.Parameters[0],
                    _navigationPropertyPathLambda.Body,
                    clauseGenerationContext);

            var includeResultOperator = new IncludeResultOperator(navigationPropertyPath);

            clauseGenerationContext.AddContextInfo(this, includeResultOperator);

            return includeResultOperator;
        }
        private static Action <TInclude> GetJoinListCallback(PropertyInfo property, IncludeResultOperator @operator, ICompiledQuery <TDoc, TOut> query)
        {
            var queryProperty = GetPropertyInfo(property, @operator);

            var included = (IList <TInclude>)(queryProperty).GetValue(query);

            if (included == null)
            {
                queryProperty.SetValue(query, new List <TInclude>());
                included = (IList <TInclude>)queryProperty.GetValue(query);
            }

            return(included.Fill);
        }
Beispiel #8
0
        protected static PropertyInfo GetPropertyInfo(PropertyInfo property, IncludeResultOperator @operator)
        {
            var target = Expression.Parameter(property.DeclaringType, "target");
            var method = property.GetGetMethod();

            var callGetMethod = Expression.Call(target, method);

            var lambda = Expression.Lambda <Func <IncludeResultOperator, LambdaExpression> >(callGetMethod, target);

            var compiledLambda = ExpressionCompiler.Compile <Func <IncludeResultOperator, LambdaExpression> >(lambda);
            var callback       = compiledLambda.Invoke(@operator);
            var mi             = (PropertyInfo)((MemberExpression)callback.Body).Member;

            return(mi);
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
        {
            var prm = Expression.Parameter(typeof(object));
            var pathFromQuerySource = Resolve(prm, prm, clauseGenerationContext);

            if (!(_navigationPropertyPathLambda.Body is MemberExpression))
            {
                throw new InvalidOperationException(CoreStrings.InvalidPropertyExpression(_navigationPropertyPathLambda));
            }

            var includeResultOperator = new IncludeResultOperator(
                _navigationPropertyPathLambda.GetComplexPropertyAccess("?not sure what goes here?").Select(p => p.Name),
                pathFromQuerySource);

            clauseGenerationContext.AddContextInfo(this, includeResultOperator);

            return(includeResultOperator);
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used 
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
        {
            var navigationPropertyPath
                = Source.Resolve(
                    _navigationPropertyPathLambda.Parameters[0],
                    _navigationPropertyPathLambda.Body,
                    clauseGenerationContext) as MemberExpression;

            if (navigationPropertyPath == null)
            {
                throw new InvalidOperationException(
                    CoreStrings.InvalidComplexPropertyExpression(_navigationPropertyPathLambda));
            }

            var includeResultOperator = new IncludeResultOperator(navigationPropertyPath);

            clauseGenerationContext.AddContextInfo(this, includeResultOperator);

            return includeResultOperator;
        }
Beispiel #11
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public static void IncludeIgnoredWarning(
            [NotNull] this IDiagnosticsLogger <DbLoggerCategory.Query> diagnostics,
            [NotNull] IncludeResultOperator includeResultOperator)
        {
            var definition = CoreStrings.LogIgnoredInclude;

            definition.Log(
                diagnostics,
                includeResultOperator.DisplayString());

            if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name))
            {
                diagnostics.DiagnosticSource.Write(
                    definition.EventId.Name,
                    new IncludeEventData(
                        definition,
                        IncludeIgnoredWarning,
                        includeResultOperator));
            }
        }
        private Action <TInclude> GetJoinDictionaryCallback(PropertyInfo property, IncludeResultOperator @operator, ICompiledQuery <TDoc, TOut> query)
        {
            var queryProperty = GetPropertyInfo(property, @operator);

            var storage = _storage.StorageFor(typeof(TInclude));

            var dictionary = (IDictionary <TKey, TInclude>)(queryProperty).GetValue(query);

            if (dictionary == null)
            {
                queryProperty.SetValue(query, new Dictionary <TKey, TInclude>());
                dictionary = (IDictionary <TKey, TInclude>)queryProperty.GetValue(query);
            }

            return(x => {
                var id = storage.Identity(x).As <TKey>();
                if (!dictionary.ContainsKey(id))
                {
                    dictionary.Add(id, x);
                }
            });
        }
Beispiel #13
0
        private IIncludeJoin doGetJoin <TInclude>(ICompiledQuery <TDoc, TOut> query, IncludeResultOperator includeOperator, IIncludeCallbackResolver <TInclude> callbackResolver) where TInclude : class
        {
            var idSource = includeOperator.IdSource as Expression <Func <TDoc, object> >;
            var joinType = (JoinType)includeOperator.JoinType.Value;

            var visitor = new FindMembers();

            visitor.Visit(idSource);
            var members = visitor.Members.ToArray();

            var mapping       = _schema.MappingFor(typeof(TDoc)).ToQueryableDocument();
            var typeContainer = new IncludeTypeContainer {
                IncludeType = includeOperator.Callback.Body.Type
            };

            var property = typeof(IncludeResultOperator).GetProperty("Callback");

            var callback = callbackResolver.Resolve(property, typeContainer);

            var included = _schema.MappingFor(typeContainer.IncludeType).ToQueryableDocument();

            return(mapping.JoinToInclude(joinType, included, members, callback));
        }
Beispiel #14
0
        private IIncludeJoin GetJoin <TInclude>(ICompiledQuery <TDoc, TOut> query, IncludeResultOperator includeOperator) where TInclude : class
        {
            var resolver = new DefaultIncludeCallbackResolver <TInclude, TDoc, TOut>(query, includeOperator);

            return(doGetJoin(query, includeOperator, resolver));
        }
Beispiel #15
0
        private IIncludeJoin GetDictionaryJoin <TKey, TInclude>(ICompiledQuery <TDoc, TOut> query, IncludeResultOperator includeOperator) where TInclude : class
        {
            var resolver = new DictionaryIncludeCallbackResolver <TKey, TInclude, TDoc, TOut>(query, includeOperator, _schema);

            return(doGetJoin <TInclude>(query, includeOperator, resolver));
        }
 public DefaultIncludeCallbackResolver(ICompiledQuery <TDoc, TOut> query, IncludeResultOperator includeOperator)
 {
     _query           = query;
     _includeOperator = includeOperator;
 }
 public DictionaryIncludeCallbackResolver(ICompiledQuery <TDoc, TOut> query, IncludeResultOperator includeOperator, StorageFeatures storage)
 {
     _query           = query;
     _includeOperator = includeOperator;
     _storage         = storage;
 }
        private static Action <TInclude> GetJoinCallback(PropertyInfo property, IncludeResultOperator @operator, ICompiledQuery <TDoc, TOut> query)
        {
            var queryProperty = GetPropertyInfo(property, @operator);

            return(x => queryProperty.SetValue(query, x));
        }
        public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index)
        {
            resultOptionType = resultOptionType ?? queryModel.SelectClause.Selector.Type;
            if (resultOperator is CastResultOperator)
            {
                CastResultOperator castResultOperator = (CastResultOperator)resultOperator;
                Type       castType = castResultOperator.CastItemType;
                MethodInfo cast     = GetMethod("Cast", expression.Type).MakeGenericMethod(castType);
                resultOptionType = castType;
                expression       = Expression.Call(cast, expression);
                return;
            }
            if (resultOperator is AllResultOperator)
            {
                AllResultOperator   allResultOperator   = (AllResultOperator)resultOperator;
                ParameterExpression parameterExpression = Expression.Parameter(selectorType, "p");
                Expression          predicateUpdate     = UpdateExpressionVisitor.Update(allResultOperator.Predicate, new[] { parameterExpression }, dbContext, queryContext);
                Expression          allLamda            = Expression.Lambda(predicateUpdate, parameterExpression);
                MethodInfo          all = GetMethod("All", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(all, new[] { expression, allLamda });
                return;
            }
            if (resultOperator is FirstResultOperator)
            {
                FirstResultOperator firstResultOperator = (FirstResultOperator)resultOperator;
                if (firstResultOperator.ReturnDefaultWhenEmpty)
                {
                    MethodInfo firstOrDefault = GetMethod("FirstOrDefault", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(firstOrDefault, new[] { expression });
                }
                else
                {
                    MethodInfo first = GetMethod("First", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(first, new[] { expression });
                }
                return;
            }
            if (resultOperator is SingleResultOperator)
            {
                SingleResultOperator singleResultOperator = (SingleResultOperator)resultOperator;
                if (singleResultOperator.ReturnDefaultWhenEmpty)
                {
                    MethodInfo firstOrDefault = GetMethod("SingleOrDefault", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(firstOrDefault, new[] { expression });
                }
                else
                {
                    MethodInfo first = GetMethod("Single", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(first, new[] { expression });
                }
                return;
            }
            if (resultOperator is AnyResultOperator)
            {
                MethodInfo any = GetMethod("Any", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(any, new[] { expression });
                return;
            }
            if (resultOperator is TrackingResultOperator)
            {
                MethodInfo asNoTracking = typeof(EntityFrameworkQueryableExtensions).GetMethod("AsNoTracking").MakeGenericMethod(selectorType);
                expression = Expression.Call(asNoTracking, new[] { expression });
                return;
            }
            if (resultOperator is CountResultOperator)
            {
                MethodInfo count = GetMethod("Count", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(count, new[] { expression });
                return;
            }
            if (resultOperator is AverageResultOperator)
            {
                MethodInfo average = GetAgregateMethod("Average", expression.Type, selectorType);
                expression = Expression.Call(average, new[] { expression });
                return;
            }
            if (resultOperator is ContainsResultOperator)
            {
                ContainsResultOperator containsResultOperator = (ContainsResultOperator)resultOperator;
                Expression             valExp;
                object value;
                ParameterExpression paramExp = containsResultOperator.Item as ParameterExpression;
                if (paramExp != null &&
                    queryContext.ParameterValues.TryGetValue(paramExp.Name, out value))
                {
                    valExp = Expression.Constant(value);
                }
                else
                {
                    valExp = containsResultOperator.Item;
                }
                if (containsResultOperator.Item is SubQueryExpression)
                {
                    SubQueryExpression subQueryExpression = (SubQueryExpression)containsResultOperator.Item;
                    QueryModelVisitor  queryModelVisitor  = new QueryModelVisitor(dbContext, queryContext);
                    queryModelVisitor.VisitQueryModel(subQueryExpression.QueryModel);
                    valExp = queryModelVisitor.expression;
                }

                MethodInfo contains = GetMethod("Contains", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(contains, new[] { expression, valExp });
                return;
            }
            if (resultOperator is DefaultIfEmptyResultOperator)
            {
                DefaultIfEmptyResultOperator defaultIfEmptyResultOperator = (DefaultIfEmptyResultOperator)resultOperator;
                MethodInfo defaultIfEmpty;
                if (defaultIfEmptyResultOperator.OptionalDefaultValue != null)
                {
                    defaultIfEmpty = GetMethod("DefaultIfEmpty", expression.Type, 1).MakeGenericMethod(selectorType);
                    expression     = Expression.Call(defaultIfEmpty, new[] { expression, defaultIfEmptyResultOperator.OptionalDefaultValue });
                }
                defaultIfEmpty = GetMethod("DefaultIfEmpty", expression.Type).MakeGenericMethod(selectorType);
                expression     = Expression.Call(defaultIfEmpty, expression);
                return;
            }
            if (resultOperator is DistinctResultOperator)
            {
                MethodInfo distinct = GetMethod("Distinct", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(distinct, expression);
                return;
            }
            if (resultOperator is GroupResultOperator)
            {
                GroupResultOperator groupResultOperator = (GroupResultOperator)resultOperator;
                Type keySelectorType = GetTypeParameter(groupResultOperator.KeySelector);
                ParameterExpression keyExpressionParam  = Expression.Parameter(keySelectorType, "p");
                Expression          keyExpression       = UpdateExpressionVisitor.Update(groupResultOperator.KeySelector, new[] { keyExpressionParam }, dbContext, queryContext);
                LambdaExpression    keyLambdaExpression = Expression.Lambda(keyExpression, keyExpressionParam);
                Type elementSelectorType = GetTypeParameter(groupResultOperator.ElementSelector);
                ParameterExpression ElementExpressionParam  = Expression.Parameter(elementSelectorType, "p");
                Expression          ElementExpression       = UpdateExpressionVisitor.Update(groupResultOperator.ElementSelector, new[] { ElementExpressionParam }, dbContext, queryContext);
                LambdaExpression    ElementLambdaExpression = Expression.Lambda(ElementExpression, ElementExpressionParam);
                Type       tSource  = queryModel.MainFromClause.ItemType;
                Type       tKey     = keyExpression.Type;
                Type       tElement = ElementExpression.Type;
                Type       tResult  = queryModel.ResultTypeOverride;
                MethodInfo groupBy  = GetMethods("GroupBy", expression.Type, 2).Where(p => p.GetParameters()[2].Name == "elementSelector").Single().
                                      MakeGenericMethod(tSource, tKey, tElement);
                expression = Expression.Call(groupBy, new[] { expression, keyLambdaExpression, ElementLambdaExpression });
                return;
            }
            if (resultOperator is LastResultOperator)
            {
                LastResultOperator lastResultOperator = (LastResultOperator)resultOperator;
                if (lastResultOperator.ReturnDefaultWhenEmpty)
                {
                    MethodInfo lastOrDefault = GetMethod("LastOrDefault", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(lastOrDefault, new[] { expression });
                }
                else
                {
                    MethodInfo last = GetMethod("Last", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(last, new[] { expression });
                }
                return;
            }
            if (resultOperator is LongCountResultOperator)
            {
                MethodInfo longCount = GetMethod("LongCount", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(longCount, new[] { expression });
                return;
            }
            if (resultOperator is MaxResultOperator)
            {
                MethodInfo max = GetMethod("Max", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(max, expression);
                return;
            }
            if (resultOperator is MinResultOperator)
            {
                MethodInfo min = GetMethod("Min", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(min, expression);
                return;
            }
            if (resultOperator is SumResultOperator)
            {
                MethodInfo sum = GetAgregateMethod("Sum", expression.Type, selectorType);
                expression = Expression.Call(sum, expression);
                return;
            }
            if (resultOperator is SkipResultOperator)
            {
                SkipResultOperator  skipResultOperator = (SkipResultOperator)resultOperator;
                Expression          expVal;
                object              value;
                ParameterExpression paramExp = skipResultOperator.Count as ParameterExpression;
                if (paramExp != null &&
                    queryContext.ParameterValues.TryGetValue(paramExp.Name, out value))
                {
                    expVal = Expression.Constant(value);
                }
                else
                {
                    expVal = skipResultOperator.Count;
                }
                MethodInfo skip = GetMethod("Skip", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(skip, new[] { expression, expVal });
                return;
            }
            if (resultOperator is TakeResultOperator)
            {
                TakeResultOperator  takeResultOperator = (TakeResultOperator)resultOperator;
                Expression          expVal;
                object              value;
                ParameterExpression paramExp = takeResultOperator.Count as ParameterExpression;
                if (paramExp != null &&
                    queryContext.ParameterValues.TryGetValue(paramExp.Name, out value))
                {
                    expVal = Expression.Constant(value);
                }
                else
                {
                    expVal = takeResultOperator.Count;
                }
                MethodInfo take = GetMethod("Take", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(take, new[] { expression, expVal });
                return;
            }
            if (resultOperator is IncludeResultOperator)
            {
                IncludeResultOperator includeResultOperator = (IncludeResultOperator)resultOperator;
                Expression            includeExpression     = includeResultOperator.NavigationPropertyPath;
                Type paramExpressionType = null;
                ParameterExpression parameterExpression = null;
                if (includeExpression is MemberExpression)
                {
                    MemberExpression memberExpression = (MemberExpression)includeExpression;
                    paramExpressionType = memberExpression.Expression.Type;
                    parameterExpression = Expression.Parameter(paramExpressionType, "p");
                    includeExpression   = Expression.Property(parameterExpression, memberExpression.Member.Name);
                }
                else
                {
                    paramExpressionType = GetTypeParameter(includeExpression);
                    parameterExpression = Expression.Parameter(paramExpressionType, "p");
                }
                Expression       updateOuterExpression   = UpdateExpressionVisitor.Update(includeExpression, new[] { parameterExpression }, dbContext, queryContext);
                LambdaExpression lambdaIncludeExpression = Expression.Lambda(updateOuterExpression, parameterExpression);
                MethodInfo       include = typeof(EntityFrameworkQueryableExtensions).GetMethods().First(m => m.Name == "Include").MakeGenericMethod(selectorType, updateOuterExpression.Type);
                expression = Expression.Call(include, new[] { expression, lambdaIncludeExpression });

                if (includeResultOperator.ChainedNavigationProperties != null)
                {
                    foreach (PropertyInfo propertyInfo in includeResultOperator.ChainedNavigationProperties)
                    {
                        Type       propertyType = propertyInfo.PropertyType;
                        Type       argument     = expression.Type.GetGenericArguments().Last();
                        MethodInfo thenInclude;
                        Type       realType;
                        if (typeof(IEnumerable).IsAssignableFrom(argument))
                        {
                            realType    = argument.GetGenericArguments().First();
                            thenInclude = ThenIncludeCollection.MakeGenericMethod(includeResultOperator.QuerySource.ItemType, realType, propertyType);
                        }
                        else
                        {
                            realType    = argument;
                            thenInclude = ThenIncludeProperty.MakeGenericMethod(includeResultOperator.QuerySource.ItemType, realType, propertyType);
                        }
                        ParameterExpression parameterThenIncludeExpression = Expression.Parameter(realType, "p");
                        MemberExpression    property = Expression.Property(parameterThenIncludeExpression, propertyInfo);
                        LambdaExpression    lambdaThenIncludeExpression = Expression.Lambda(property, parameterThenIncludeExpression);
                        expression = Expression.Call(thenInclude, new[] { expression, lambdaThenIncludeExpression });
                    }
                }
                return;
            }
            if (resultOperator is OfTypeResultOperator)
            {
                OfTypeResultOperator ofTypeResultOperator = (OfTypeResultOperator)resultOperator;
                selectorType = ofTypeResultOperator.SearchedItemType;
                var miOfType = GetMethod("OfType", expression.Type).MakeGenericMethod(ofTypeResultOperator.SearchedItemType);
                expression = Expression.Call(miOfType, new[] { expression });
                return;
            }
            throw new NotSupportedException();
        }
Beispiel #20
0
 public DictionaryIncludeCallbackResolver(ICompiledQuery <TDoc, TOut> query, IncludeResultOperator includeOperator, IDocumentSchema schema)
 {
     _query           = query;
     _includeOperator = includeOperator;
     _schema          = schema;
 }
        /// <summary>
        ///    Copied from EntityFramework Core source code
        /// </summary>
        private IEnumerable <INavigation> BindChainedNavigations(IEnumerable <INavigation> boundNavigations, IncludeResultOperator includeResultOperator)
        {
            var boundNavigationsList = boundNavigations.ToList();

            if (includeResultOperator.ChainedNavigationProperties != null)
            {
                foreach (var propertyInfo in includeResultOperator.ChainedNavigationProperties)
                {
                    var lastNavigation = boundNavigationsList.Last();
                    var navigation     = lastNavigation.GetTargetType().FindNavigation(propertyInfo.Name);

                    if (navigation == null)
                    {
                        return(null);
                    }
                    boundNavigationsList.Add(navigation);
                }
            }

            var replaced = includeResultOperator as ReplaceIncludeResultOperator;

            if (replaced != null)
            {
                // match expressions to navigation
                foreach (var navigation in boundNavigationsList)
                {
                    var name = $"{navigation.DeclaringEntityType.Name}-{navigation.Name}";
                    HashSet <Expression> expressions;
                    if (replaced.Expressions.TryGetValue(name, out expressions))
                    {
                        this.ExpressionCollection.AddOrUpdate(navigation, expressions);
                    }
                }
            }

            return(boundNavigationsList);
        }