public void HandleSubscription(CollectionSubscription subscription, Type dbContextType, IServiceProvider requestServiceProvider, ConnectionBase connection, KeyValuePair <Type, string> property, List <ChangeResponse> collectionChanges, List <ChangeResponse> allChanges) { try { bool anyCollectionChanges = collectionChanges.Any(); if ((anyCollectionChanges && subscription.Prefilters.Any(prefilter => prefilter is IAfterQueryPrefilter || prefilter is TakePrefilter || prefilter is SkipPrefilter)) || HasIncludePrefilterWithChange(subscription, allChanges)) { SapphireDbContext db = dbContextAccessor.GetContext(dbContextType, requestServiceProvider); IQueryable <object> collectionValues = db.GetCollectionValues(requestServiceProvider, connection.Information, property, subscription.Prefilters); IAfterQueryPrefilter afterQueryPrefilter = subscription.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = afterQueryPrefilter.Execute(collectionValues) }); } else { _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = collectionValues .AsEnumerable() .Select(v => v.GetAuthenticatedQueryModel(connection.Information, serviceProvider)) .ToList() }); } } else if (anyCollectionChanges) { IEnumerable <WherePrefilter> wherePrefilters = subscription.Prefilters.OfType <WherePrefilter>(); foreach (WherePrefilter wherePrefilter in wherePrefilters) { wherePrefilter.Initialize(property.Key); Func <object, bool> whereFunction = wherePrefilter.WhereExpression.Compile(); collectionChanges = collectionChanges.Where((change) => whereFunction(change.Value)).ToList(); } collectionChanges.ForEach(change => { object value = change.Value.GetAuthenticatedQueryModel(connection.Information, requestServiceProvider); _ = connection.Send(change.CreateResponse(subscription.ReferenceId, value)); }); } } catch (Exception ex) { SubscribeCommand tempErrorCommand = new SubscribeCommand() { CollectionName = subscription.CollectionName, ReferenceId = subscription.ReferenceId, Prefilters = subscription.Prefilters }; _ = connection.Send(tempErrorCommand.CreateExceptionResponse <ResponseBase>(ex)); logger.LogError( $"Error handling subscription '{subscription.ReferenceId}' of {subscription.CollectionName}"); logger.LogError(ex.Message); } }
public void HandleSubscription(CollectionSubscription subscription, Type dbContextType, IServiceProvider requestServiceProvider, ConnectionBase connection, KeyValuePair <Type, string> property, List <ChangeResponse> collectionChanges, List <ChangeResponse> allChanges) { try { bool anyCollectionChanges = collectionChanges.Any(); if ((anyCollectionChanges && subscription.Prefilters.Any(prefilter => prefilter is IAfterQueryPrefilter || prefilter is TakePrefilter || prefilter is SkipPrefilter)) || HasIncludePrefilterWithChange(subscription, allChanges)) { SapphireDbContext db = dbContextAccessor.GetContext(dbContextType, requestServiceProvider); IQueryable <object> collectionValues = db.GetCollectionValues(requestServiceProvider, connection.Information, property, subscription.Prefilters); IAfterQueryPrefilter afterQueryPrefilter = subscription.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = afterQueryPrefilter.Execute(collectionValues) }); } else { _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = collectionValues .AsEnumerable() .Select(v => v.GetAuthenticatedQueryModel(connection.Information, serviceProvider)) .ToList() }); } } else if (anyCollectionChanges) { IEnumerable <WherePrefilter> wherePrefilters = subscription.Prefilters.OfType <WherePrefilter>(); List <ChangeResponse> oldValuesUnloadResponses = new List <ChangeResponse>(); List <ChangeResponse> newValuesLoadResponses = new List <ChangeResponse>(); foreach (WherePrefilter wherePrefilter in wherePrefilters) { wherePrefilter.Initialize(property.Key); // Values that did change know do match the oldValuesUnloadResponses.AddRange( collectionChanges .Where(change => change.State == ChangeResponse.ChangeState.Modified && !wherePrefilter.WhereExpressionCompiled(change.Value) && wherePrefilter.WhereExpressionCompiled(change.OriginalValue)) .Select(change => { ChangeResponse newChangeResponse = change.CreateResponse(null, change.Value); newChangeResponse.State = ChangeResponse.ChangeState.Deleted; return(newChangeResponse); }) ); newValuesLoadResponses.AddRange( collectionChanges .Where(change => change.State == ChangeResponse.ChangeState.Modified && wherePrefilter.WhereExpressionCompiled(change.Value) && !wherePrefilter.WhereExpressionCompiled(change.OriginalValue)) .Select(change => { ChangeResponse newChangeResponse = change.CreateResponse(null, change.Value); newChangeResponse.State = ChangeResponse.ChangeState.Added; return(newChangeResponse); }) ); collectionChanges = collectionChanges .Where((change) => wherePrefilter.WhereExpressionCompiled(change.Value)).ToList(); } IEnumerable <ChangeResponse> changesForWherePrefilter = oldValuesUnloadResponses .Concat(newValuesLoadResponses) .GroupBy(v => v.Value) .Select(g => g.LastOrDefault()); collectionChanges = collectionChanges.Concat(changesForWherePrefilter).ToList(); ChangesResponse changesResponse = new ChangesResponse() { ReferenceId = subscription.ReferenceId, Changes = collectionChanges.Select(change => { object value = change.Value.GetAuthenticatedQueryModel(connection.Information, requestServiceProvider); return(change.CreateResponse(subscription.ReferenceId, value)); }).ToList() }; if (changesResponse.Changes.Any()) { _ = connection.Send(changesResponse); } } } catch (Exception ex) { SubscribeCommand tempErrorCommand = new SubscribeCommand() { CollectionName = subscription.CollectionName, ReferenceId = subscription.ReferenceId, Prefilters = subscription.Prefilters }; _ = connection.Send(tempErrorCommand.CreateExceptionResponse <ResponseBase>(ex)); logger.LogError( $"Error handling subscription '{subscription.ReferenceId}' of {subscription.CollectionName}"); logger.LogError(ex.Message); } }