public void AddSubscription(string contextName, string collectionName, List <IPrefilterBase> prefilters, ConnectionBase connection, string referenceId) { contextName = contextName.ToLowerInvariant(); collectionName = collectionName.ToLowerInvariant(); try { readerWriterLockSlim.EnterWriteLock(); if (!subscriptions.TryGetValue(contextName, out Dictionary <string, Dictionary <PrefilterContainer, List <Subscription> > > subscriptionsOfContext)) { subscriptionsOfContext = new Dictionary <string, Dictionary <PrefilterContainer, List <Subscription> > >( StringComparer.InvariantCultureIgnoreCase); subscriptions.Add(contextName, subscriptionsOfContext); } if (!subscriptionsOfContext.TryGetValue(collectionName, out Dictionary <PrefilterContainer, List <Subscription> > subscriptionsOfCollection)) { subscriptionsOfCollection = new Dictionary <PrefilterContainer, List <Subscription> >(); subscriptionsOfContext.Add(collectionName, subscriptionsOfCollection); } PrefilterContainer prefilterContainer = new PrefilterContainer(prefilters); if (!subscriptionsOfCollection.TryGetValue(prefilterContainer, out List <Subscription> equalCollectionSubscriptions)) { equalCollectionSubscriptions = new List <Subscription>(); subscriptionsOfCollection.Add(prefilterContainer, equalCollectionSubscriptions); } Subscription subscription = new Subscription() { Connection = connection, ReferenceId = referenceId }; equalCollectionSubscriptions.Add(subscription); } finally { readerWriterLockSlim.ExitWriteLock(); } }
private void HandleEqualCollectionSubscriptions(PrefilterContainer prefilterContainer, List <Subscription> equalCollectionSubscriptions, IGrouping <string, ChangeResponse> collectionChanges, Type dbContextType, List <ChangeResponse> changes, KeyValuePair <Type, string> property, ModelAttributesInfo modelAttributesInfo, Guid handlingId) { List <IPrefilterBase> prefilters = prefilterContainer.Prefilters; if (prefilters.Any(prefilter => prefilter is IAfterQueryPrefilter || prefilter is TakePrefilter || prefilter is SkipPrefilter || prefilter is IncludePrefilter)) { HandleReloadOfCollectionData(dbContextType, property, prefilterContainer, equalCollectionSubscriptions, handlingId); } else { HandleRelativeChangesOfCollection(modelAttributesInfo, property, collectionChanges, prefilters, equalCollectionSubscriptions); } }
private void HandleReloadOfCollectionData(Type dbContextType, KeyValuePair <Type, string> property, PrefilterContainer prefilterContainer, List <Subscription> equalCollectionSubscriptions, Guid handlingId) { try { if (!prefilterContainer.StartHandling(handlingId)) { return; } SapphireDbContext db = dbContextAccessor.GetContext(dbContextType, serviceProvider); IQueryable <object> collectionValues = db.GetCollectionValues(property, prefilterContainer.Prefilters); IAfterQueryPrefilter afterQueryPrefilter = prefilterContainer.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); object result = afterQueryPrefilter.Execute(collectionValues); Parallel.ForEach(equalCollectionSubscriptions, subscription => { Task.Run(() => { _ = subscription.Connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = result }); }); }); } else { List <object> values = collectionValues.ToList(); Parallel.ForEach(equalCollectionSubscriptions, subscription => { Task.Run(() => { _ = subscription.Connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = values .Where(v => property.Key.CanQueryEntry(subscription.Connection.Information, serviceProvider, v)) .Select(v => v.GetAuthenticatedQueryModel(subscription.Connection.Information, serviceProvider)) .ToList() }); }); }); } } finally { prefilterContainer.FinishHandling(); } }