private static string GetQueryHash(IRepositoryQuery query) { // org ids, project ids, date ranges, filter expression var appFilter = query.GetAppFilter(); var projectIds = query.GetProjects(); if (projectIds.Count == 0 && appFilter?.Projects != null) { projectIds.AddRange(appFilter.Projects.Select(p => p.Id)); } var organizationIds = query.GetOrganizations(); if (organizationIds.Count == 0 && appFilter?.Organizations != null) { organizationIds.AddRange(appFilter.Organizations.Select(o => o.Id)); } var hashCode = new HashCode(); if (projectIds.Count > 0) { foreach (string projectId in projectIds) { hashCode.Add(projectId); } } else if (organizationIds.Count > 0) { foreach (string organizationId in organizationIds) { hashCode.Add(organizationId); } } var dateRanges = query.GetDateRanges(); var minDate = dateRanges.Min(r => r.StartDate) ?? DateTime.MinValue; var maxDate = dateRanges.Max(r => r.EndDate) ?? DateTime.MaxValue; hashCode.Add(minDate); hashCode.Add(maxDate); hashCode.Add(query.GetFilterExpression()); string cacheScope = ""; if (organizationIds.Count == 1 && projectIds.Count == 1) { cacheScope = String.Concat(organizationIds.Single(), ":", projectIds.Single(), ":"); } else if (organizationIds.Count == 1) { cacheScope = String.Concat(organizationIds.Single(), ":"); } else if (projectIds.Count == 1) { cacheScope = String.Concat("project:", projectIds.Single(), ":"); } return(String.Concat(cacheScope, hashCode.ToHashCode().ToString())); }