Ejemplo n.º 1
0
        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();
            }
        }