public void AddQuery(OeCacheContext cacheContext, Object query, Expression countExpression, OeEntryFactory entryFactory, OePropertyAccessor[] skipTokenAccessors) { var queryCacheItem = new QueryCacheItem(query, countExpression, entryFactory, skipTokenAccessors); _cache.TryAdd(cacheContext, queryCacheItem); }
private static IAsyncEnumerable <TResult> GetFromCache <TResult>(OeQueryContext queryContext, T dbContext, Db.OeQueryCache queryCache) { OeCacheContext cacheContext = queryContext.CreateCacheContext(); Db.QueryCacheItem queryCacheItem = queryCache.GetQuery(cacheContext); Func <QueryContext, IAsyncEnumerable <TResult> > queryExecutor; Expression countExpression; IReadOnlyList <Db.OeQueryCacheDbParameterValue> parameterValues; if (queryCacheItem == null) { IQueryable query = queryContext.EntitySetAdapter.GetEntitySet(dbContext); var parameterVisitor = new OeConstantToParameterVisitor(false); Expression expression = queryContext.CreateExpression(query, parameterVisitor); queryExecutor = dbContext.CreateAsyncQueryExecutor <TResult>(expression); countExpression = queryContext.CreateCountExpression(query, expression); queryCache.AddQuery(queryContext.CreateCacheContext(parameterVisitor.ConstantToParameterMapper), queryExecutor, countExpression, queryContext.EntryFactory, queryContext.SkipTokenParser?.Accessors); parameterValues = parameterVisitor.ParameterValues; } else { queryExecutor = (Func <QueryContext, IAsyncEnumerable <TResult> >)queryCacheItem.Query; queryContext.EntryFactory = queryCacheItem.EntryFactory; if (queryContext.SkipTokenParser != null) { queryContext.SkipTokenParser.Accessors = queryCacheItem.SkipTokenAccessors; } countExpression = queryCacheItem.CountExpression; parameterValues = cacheContext.ParameterValues; } var queryContextFactory = dbContext.GetService <IQueryContextFactory>(); QueryContext efQueryContext = queryContextFactory.Create(); foreach (Db.OeQueryCacheDbParameterValue parameterValue in parameterValues) { efQueryContext.AddParameter(parameterValue.ParameterName, parameterValue.ParameterValue); } if (queryContext.ODataUri.QueryCount.GetValueOrDefault()) { queryContext.CountExpression = new OeParameterToVariableVisitor().Translate(countExpression, parameterValues); } return(queryExecutor(efQueryContext)); }
public void Test() { SelectTestDefinition[] requestMethodNames = SelectTestDefinition.GetSelectTestDefinitions(); requestMethodNames = requestMethodNames.Where(t => t.MethodName == "FilterEnum" || t.MethodName == "FilterEnumNull").ToArray(); var fixture = new DbFixtureInitDb(); var parser = new OeGetParser(fixture.OeDataAdapter, fixture.EdmModel); for (int i = 0; i < requestMethodNames.Length; i++) { OeQueryContext queryContext1 = parser.CreateQueryContext(fixture.ParseUri(requestMethodNames[i].Request), 0, false, OeMetadataLevel.Minimal); OeQueryContext queryContext2 = parser.CreateQueryContext(fixture.ParseUri(requestMethodNames[i].Request), 0, false, OeMetadataLevel.Minimal); var constantToParameterMapper = new FakeReadOnlyDictionary <ConstantNode, Db.OeQueryCacheDbParameterDefinition>(); if (queryContext1.ODataUri.Skip != null) { var constantNode = OeCacheComparerParameterValues.CreateSkipConstantNode((int)queryContext1.ODataUri.Skip.Value, queryContext1.ODataUri.Path); constantToParameterMapper.Add(constantNode, new Db.OeQueryCacheDbParameterDefinition("p_0", typeof(int))); } if (queryContext1.ODataUri.Top != null) { var constantNode = OeCacheComparerParameterValues.CreateTopConstantNode((int)queryContext1.ODataUri.Top.Value, queryContext1.ODataUri.Path); constantToParameterMapper.Add(constantNode, new Db.OeQueryCacheDbParameterDefinition($"p_{constantToParameterMapper.Count}", typeof(int))); } OeCacheContext cacheContext1 = queryContext1.CreateCacheContext(); OeCacheContext cacheContext2 = queryContext2.CreateCacheContext(); bool result = new OeCacheComparer(constantToParameterMapper, false).Compare(cacheContext1, cacheContext2); Assert.True(result); for (int j = i + 1; j < requestMethodNames.Length; j++) { queryContext2 = parser.CreateQueryContext(fixture.ParseUri(requestMethodNames[j].Request), 0, false, OeMetadataLevel.Minimal); constantToParameterMapper = new FakeReadOnlyDictionary <ConstantNode, Db.OeQueryCacheDbParameterDefinition>(); result = new OeCacheComparer(constantToParameterMapper, false).Compare(cacheContext1, cacheContext2); Assert.False(result); } } }
public static int GetCacheCode(OeCacheContext cacheContext) { var hashVistitor = new OeQueryNodeHashVisitor(); ODataUri uri = cacheContext.ODataUri; int hash = uri.Path.FirstSegment.Identifier.GetHashCode(); hash = CombineHashCodes(hash, uri.Path.LastSegment.Identifier.GetHashCode()); if (cacheContext.ParseNavigationSegments != null) { for (int i = 0; i < cacheContext.ParseNavigationSegments.Count; i++) { OeParseNavigationSegment parseNavigationSegment = cacheContext.ParseNavigationSegments[i]; if (parseNavigationSegment.Filter != null) { int h = hashVistitor.TranslateNode(cacheContext.ParseNavigationSegments[i].Filter.Expression); hash = CombineHashCodes(hash, h); } } } if (uri.Filter != null) { hash = CombineHashCodes(hash, hashVistitor.TranslateNode(uri.Filter.Expression)); } if (uri.Apply != null) { foreach (TransformationNode transformationNode in uri.Apply.Transformations) { if (transformationNode is FilterTransformationNode) { FilterClause filter = (transformationNode as FilterTransformationNode).FilterClause; hash = CombineHashCodes(hash, hashVistitor.TranslateNode(filter.Expression)); } else if (transformationNode is AggregateTransformationNode) { foreach (AggregateExpression aggregate in (transformationNode as AggregateTransformationNode).Expressions) { hash = CombineHashCodes(hash, (int)aggregate.Method); } } else if (transformationNode is GroupByTransformationNode) { foreach (GroupByPropertyNode group in (transformationNode as GroupByTransformationNode).GroupingProperties) { hash = CombineHashCodes(hash, group.Name.GetHashCode()); } } else { throw new InvalidProgramException("unknown TransformationNode " + transformationNode.GetType().ToString()); } } } if (uri.SelectAndExpand != null) { hash = GetCacheCode(hash, uri.SelectAndExpand); } if (uri.OrderBy != null) { hash = CombineHashCodes(hash, (int)uri.OrderBy.Direction); hash = CombineHashCodes(hash, hashVistitor.TranslateNode(uri.OrderBy.Expression)); } return(hash); }
public bool Compare(OeCacheContext cacheContext1, OeCacheContext cacheContext2) { if (cacheContext1.EntitySet != cacheContext2.EntitySet) { return(false); } if (cacheContext1.NavigationNextLink != cacheContext2.NavigationNextLink) { return(false); } if (cacheContext1.MetadataLevel != cacheContext2.MetadataLevel) { return(false); } ODataUri uri1 = cacheContext1.ODataUri; ODataUri uri2 = cacheContext2.ODataUri; if (!ODataPathComparer.Compare(uri1.Path, uri2.Path)) { return(false); } if (!CompareParseNavigationSegments(cacheContext1.ParseNavigationSegments, cacheContext2.ParseNavigationSegments)) { return(false); } if (!CompareApply(uri1.Apply, uri2.Apply)) { return(false); } if (!CompareFilter(uri1.Filter, uri2.Filter, false)) { return(false); } if (!CompareSelectAndExpand(uri1.SelectAndExpand, uri2.SelectAndExpand, uri1.Path)) { return(false); } if (!CompareOrderBy(uri1.OrderBy, uri2.OrderBy, false)) { return(false); } if (!CompareSkip(uri1.Skip, uri2.Skip, uri1.Path)) { return(false); } if (!CompareTop(uri1.Top, uri2.Top, uri1.Path)) { return(false); } if (!CompareSkipToken(uri1.SkipToken, uri2.SkipToken, cacheContext1.SkipTokenParser)) { return(false); } return(true); }
public QueryCacheItem GetQuery(OeCacheContext cacheContext) { _cache.TryGetValue(cacheContext, out QueryCacheItem cacheItem); return(cacheItem); }