Ejemplo n.º 1
0
        protected virtual void TrackEntitiesInResults <TResult>(
            [NotNull] QueryModel queryModel,
            [NotNull] ICollection <QueryAnnotation> queryAnnotations)
        {
            Check.NotNull(queryModel, "queryModel");
            Check.NotNull(queryAnnotations, "queryAnnotations");

            if (!typeof(TResult).GetTypeInfo()
                .IsAssignableFrom(queryModel.SelectClause.Selector.Type.GetTypeInfo()))
            {
                return;
            }

            var querySourceReferenceExpressionsToTrack
                = new EntityResultFindingExpressionTreeVisitor(QueryCompilationContext.Model)
                  .FindEntitiesInResult(queryModel.SelectClause.Selector)
                  .Where(qsre => !queryAnnotations
                         .Any(qa => qa.ResultOperator is AsNoTrackingResultOperator &&
                              qa.QuerySource == qsre.ReferencedQuerySource))
                  .ToList();

            if (querySourceReferenceExpressionsToTrack.Any())
            {
                QueryCompilationContext.Logger
                .WriteInformation(
                    querySourceReferenceExpressionsToTrack,
                    qsres => Strings.FormatLogTrackingQuerySources(
                        qsres.Select(qsre => qsre.ReferencedQuerySource.ItemName).Join()));

                _expression
                    = Expression.Call(
                          LinqOperatorProvider.TrackEntities
                          .MakeGenericMethod(
                              typeof(TResult),
                              queryModel.SelectClause.Selector.Type),
                          _expression,
                          QueryContextParameter,
                          Expression.Constant(
                              _getEntityAccessors
                              .MakeGenericMethod(queryModel.SelectClause.Selector.Type)
                              .Invoke(null, new object[]
                {
                    querySourceReferenceExpressionsToTrack,
                    queryModel.SelectClause.Selector
                })));
            }
        }
        protected virtual void TrackEntitiesInResults <TResult>(
            [NotNull] QueryModel queryModel)
        {
            Check.NotNull(queryModel, nameof(queryModel));

            if (queryModel.GetOutputDataInfo() is StreamedScalarValueInfo)
            {
                return;
            }

            var entityTrackingInfos
                = new EntityResultFindingExpressionTreeVisitor(QueryCompilationContext)
                  .FindEntitiesInResult(queryModel.SelectClause.Selector);

            if (entityTrackingInfos.Any())
            {
                QueryCompilationContext.Logger
                .LogInformation(
                    entityTrackingInfos,
                    etis => Strings.LogTrackingQuerySources(
                        etis.Select(eti => eti.QuerySource.ItemName).Join()));

                var resultItemType
                    = _expression.Type.GetSequenceType();

                var resultItemTypeInfo = resultItemType.GetTypeInfo();

                MethodInfo trackingMethod;

                if (resultItemTypeInfo.IsGenericType &&
                    (resultItemTypeInfo.GetGenericTypeDefinition() == typeof(IGrouping <,>) ||
                     resultItemTypeInfo.GetGenericTypeDefinition() == typeof(IAsyncGrouping <,>)))
                {
                    trackingMethod
                        = LinqOperatorProvider.TrackGroupedEntities
                          .MakeGenericMethod(
                              resultItemType.GenericTypeArguments[0],
                              resultItemType.GenericTypeArguments[1],
                              queryModel.SelectClause.Selector.Type);
                }
                else
                {
                    trackingMethod
                        = LinqOperatorProvider.TrackEntities
                          .MakeGenericMethod(
                              resultItemType,
                              queryModel.SelectClause.Selector.Type);
                }

                _expression
                    = Expression.Call(
                          trackingMethod,
                          _expression,
                          QueryContextParameter,
                          Expression.Constant(entityTrackingInfos),
                          Expression.Constant(
                              _getEntityAccessors
                              .MakeGenericMethod(queryModel.SelectClause.Selector.Type)
                              .Invoke(
                                  null,
                                  new object[]
                {
                    entityTrackingInfos,
                    queryModel.SelectClause.Selector
                })));
            }
        }