public async Task UpdateEntityToProjectionAsync(ProjectionSourceDescriptor projectionSource, IProjectionResult projectionResult, bool addEntityToProjections, CancellationToken cancellation) { if (addEntityToProjections) { var projectionId = GetProjectionId(projectionResult); var addedProjection = new ProjectionTargetDescriptor <TProjectionId>(typeof(TProjection), projectionId); var(originalMetadata, metadata) = await GetMetadataAsync(addedProjection, cancellation); Assert(!metadata.ProjectionSources.Any(p => p.Id == projectionSource.SourceId && p.Type == projectionSource.SourceType.GetUnqualifiedTypeName())); var storedProjectionSource = new ProjectionSource { Id = projectionSource.SourceId, Type = projectionSource.SourceType.GetUnqualifiedTypeName() }; metadata.ProjectionSources.Add(storedProjectionSource); _targetMetadataCache[addedProjection] = new ProjectionTargetMetadataCacheEntry(originalMetadata, metadata, touched: true); } _targetsToUpdate.Add((TProjection)projectionResult.Result); }
private async ValueTask <ProjectionTargetMetadataCacheEntry> GetMetadataAsync(ProjectionTargetDescriptor <TProjectionId> target, CancellationToken cancellation) { if (!_targetMetadataCache.TryGetValue(target, out var entry)) { var entryId = ProjectionTargetMetadata.GenerateId(target.TargetId.ToString(), target.TargetType.GetUnqualifiedTypeName()); var metadata = await _database.GetAsync <ProjectionTargetMetadata>(p => p.Id == entryId, cancellation).FirstOrDefault(); var originalMetadata = metadata; var touched = false; if (metadata == null) { metadata = new ProjectionTargetMetadata { TargetId = target.TargetId, TargetType = target.TargetType.GetUnqualifiedTypeName() }; touched = true; } entry = new ProjectionTargetMetadataCacheEntry(originalMetadata, metadata, touched); _targetMetadataCache.Add(target, entry); } return(entry); }
private async ValueTask <ProjectionTargetMetadataCacheEntry> GetMetadataAsync(ProjectionTargetDescriptor target, CancellationToken cancellation) { if (!_targetMetadataCache.TryGetValue(target, out var entry)) { var entryId = ProjectionTargetMetadata.GenerateId(target.TargetId, target.TargetType.GetUnqualifiedTypeName()); var metadata = await _database.GetAsync <ProjectionTargetMetadata>(p => p.Id == entryId, cancellation).FirstOrDefault(); entry = new ProjectionTargetMetadataCacheEntry(metadata, metadata, touched: false); if (metadata != null) { _targetMetadataCache.Add(target, entry); } } return(entry); }
public async Task RemoveEntityFromProjectionAsync(ProjectionSourceDescriptor projectionSource, ProjectionTargetDescriptor removedProjection, CancellationToken cancellation) { var(originalMetadata, metadata) = await GetMetadataAsync(removedProjection, cancellation); if (metadata == null) { Assert(false); return; } var removed = metadata.ProjectionSources .RemoveFirstWhere(p => p.Id == projectionSource.SourceId && p.Type == projectionSource.SourceType.GetUnqualifiedTypeName()); Assert(removed != null); if (!metadata.ProjectionSources.Any()) { _targetMetadataCache[removedProjection] = new ProjectionTargetMetadataCacheEntry(originalMetadata, metadata: null, touched: true); var predicate = DataPropertyHelper.BuildPredicate <TProjectionId, TProjection>(metadata.TargetId); var projection = await _database.GetAsync(predicate, cancellation).FirstOrDefault(); if (projection != null) { _targetsToDelete.Add(projection); //await _database.RemoveAsync(projection, cancellation); } } _targetMetadataCache[removedProjection] = new ProjectionTargetMetadataCacheEntry(originalMetadata, metadata, touched: true); }