public static List <QueryEntity> CherryPickSelectedProperties <TQueryableEntity>( this IEnumerable <QueryEntity> entities, QueryClause <TQueryableEntity> query, RepositoryEntityMetadata metadata, IEnumerable <string> includeAdditionalProperties = null) where TQueryableEntity : IQueryableEntity { var selectedPropertyNames = query.GetAllSelectedFields(); if (!selectedPropertyNames.Any()) { return(entities.ToList()); } selectedPropertyNames = selectedPropertyNames .Concat(new[] { nameof(QueryEntity.Id) }) .Concat(includeAdditionalProperties ?? Enumerable.Empty <string>()) .ToList(); return(entities .Select(resultEntity => resultEntity.Properties .Where(resultEntityProperty => selectedPropertyNames.Contains(resultEntityProperty.Key))) .Select(selectedProperties => EntityFromContainerProperties(selectedProperties.ToObjectDictionary(), metadata)) .ToList()); }
public static CommandEntity FromProperties(IReadOnlyDictionary <string, object> properties, RepositoryEntityMetadata metadata) { properties.GuardAgainstNull(nameof(properties)); metadata.GuardAgainstNull(nameof(metadata)); if (!properties.ContainsKey(nameof(Id)) || properties[nameof(Id)] == null) { throw new InvalidOperationException( "Unable to create a new CommandEntity. There is no 'Id' property in this collection of values."); } var result = new CommandEntity(properties[nameof(Id)].ToString()); foreach (var property in properties) { var propertyType = metadata.GetPropertyType(property.Key, false); if (propertyType != null) { result.Add(property.Key, property.Value, propertyType); } } return(result); }
protected RepositoryEntity(string id) { Metadata = new RepositoryEntityMetadata(); Add(nameof(Id), id, typeof(string)); Add(nameof(LastPersistedAtUtc), null, typeof(DateTime?)); Add(nameof(IsDeleted), null, typeof(bool?)); }
public void Delete(Identifier id, bool destroy = true) { id.GuardAgainstNull(nameof(id)); var entity = this.repository.Retrieve(this.containerName, id, RepositoryEntityMetadata.FromType <TEntity>()); if (entity == null) { return; } if (destroy) { this.repository.Remove(this.containerName, id); this.recorder.TraceDebug("Entity {Id} was destroyed in repository", id); return; } if (entity.IsDeleted.GetValueOrDefault(false)) { return; } entity.IsDeleted = true; this.repository.Replace(this.containerName, id, entity); this.recorder.TraceDebug("Entity {Id} was soft-deleted in repository", id); }
public static CommandEntity FromCommandEntity(IReadOnlyDictionary <string, object> properties, RepositoryEntityMetadata metadata) { properties.GuardAgainstNull(nameof(properties)); metadata.GuardAgainstNull(nameof(metadata)); return(FromProperties(properties, metadata)); }
public TEntity ResurrectDeleted(Identifier id) { var entity = this.repository.Retrieve(this.containerName, id, RepositoryEntityMetadata.FromType <TEntity>()); if (entity == null) { return(default);
private static QueryEntity FromProperties <TType>(IReadOnlyDictionary <string, object> properties) where TType : IQueryableEntity { properties.GuardAgainstNull(nameof(properties)); var metadata = RepositoryEntityMetadata.FromType <TType>(); return(FromProperties(properties, metadata)); }
public TDtoWithId Get <TDtoWithId>(Identifier id, bool includeDeleted = false) where TDtoWithId : IQueryableEntity, IHasIdentity, new() { id.GuardAgainstNull(nameof(id)); var entity = this.repository.Retrieve(this.containerName, id, RepositoryEntityMetadata.FromType <TDto>()); if (entity == null) { return(default);
public TDtoWithId Get <TDtoWithId>(Identifier id) where TDtoWithId : IQueryableEntity, IHasIdentity, new() { id.GuardAgainstNull(nameof(id)); var entity = this.repository.Retrieve(this.containerName, id, RepositoryEntityMetadata.FromType <TDto>()); this.logger.LogDebug($"Entity {id} was retrieved from repository"); return(entity == null ? default : entity.ToQueryDto <TDtoWithId>()); }
public TEntity Get(Identifier id) { id.GuardAgainstNull(nameof(id)); var entity = this.repository.Retrieve(this.containerName, id, RepositoryEntityMetadata.FromType <TEntity>()); this.logger.LogDebug("Entity {Id} was retrieved from repository", id); return(entity != null ? entity.ToDomainEntity <TEntity>(this.domainFactory) : default);
public CommandEntity Retrieve(string containerName, string id, RepositoryEntityMetadata metadata) { containerName.GuardAgainstNullOrEmpty(nameof(containerName)); id.GuardAgainstNullOrEmpty(nameof(id)); metadata.GuardAgainstNull(nameof(metadata)); var container = EnsureContainer(containerName); if (container.Exists(id)) { return(CommandEntity.FromCommandEntity( container.Get(id).FromFileProperties(metadata), metadata)); } return(default);
public CommandEntity Retrieve(string containerName, string id, RepositoryEntityMetadata metadata) { containerName.GuardAgainstNullOrEmpty(nameof(containerName)); id.GuardAgainstNullOrEmpty(nameof(id)); metadata.GuardAgainstNull(nameof(metadata)); if (this.containers.ContainsKey(containerName)) { if (this.containers[containerName].ContainsKey(id)) { return(CommandEntity.FromCommandEntity( this.containers[containerName][id].FromDictionaryProperties(), metadata)); } } return(default);
public QueryResults <TDto> Query(QueryClause <TDto> query) { if (query == null || query.Options.IsEmpty) { this.logger.LogDebug("No entities were retrieved from repository, the query is empty"); return(new QueryResults <TDto>(new List <TDto>())); } var entities = this.repository.Query(this.containerName, query, RepositoryEntityMetadata.FromType <TDto>()); this.logger.LogDebug($"{entities.Count} Entities were retrieved from repository"); return(new QueryResults <TDto>(entities.ConvertAll(x => x.ToEntity <TDto>(this.domainFactory)))); }
public QueryResults <TDto> Query(QueryClause <TDto> query, bool includeDeleted = false) { if (query == null || query.Options.IsEmpty) { this.recorder.TraceDebug("No entities were retrieved from repository, the query is empty"); return(new QueryResults <TDto>(new List <TDto>())); } var entities = this.repository.Query(this.containerName, query, RepositoryEntityMetadata.FromType <TDto>()); entities = entities .Where(e => !e.IsDeleted.GetValueOrDefault(false) || includeDeleted) .ToList(); this.recorder.TraceDebug($"{entities.Count} Entities were retrieved from repository"); return(new QueryResults <TDto>(entities.ConvertAll(x => x.ToEntity <TDto>(this.domainFactory)))); }
public static QueryEntity FromProperties(IReadOnlyDictionary <string, object> properties, RepositoryEntityMetadata metadata) { properties.GuardAgainstNull(nameof(properties)); metadata.GuardAgainstNull(nameof(metadata)); var dataEntity = new QueryEntity(); foreach (var pair in properties) { var propertyType = metadata.GetPropertyType(pair.Key, false); if (propertyType != null) { dataEntity.Add(pair.Key, pair.Value, propertyType); } } return(dataEntity); }
public TDto Update(string id, Action <TDto> action) { id.GuardAgainstNullOrEmpty(nameof(id)); action.GuardAgainstNull(nameof(action)); var entity = this.repository.Retrieve(ContainerName, id, RepositoryEntityMetadata.FromType <TDto>()); if (entity == null) { throw new ResourceNotFoundException(); } var dto = entity.ToReadModelEntity <TDto>(); action(dto); var updated = this.repository.Replace(ContainerName, id, CommandEntity.FromType(dto)); this.logger.LogDebug("Updated read model for entity {Id}", id); return(updated.ToReadModelEntity <TDto>()); }
public static List <QueryEntity> JoinResults(this JoinDefinition joinDefinition, IReadOnlyDictionary <string, IReadOnlyDictionary <string, object> > leftEntities, IReadOnlyDictionary <string, IReadOnlyDictionary <string, object> > rightEntities, RepositoryEntityMetadata metadata, Func <KeyValuePair <string, IReadOnlyDictionary <string, object> >, KeyValuePair <string, IReadOnlyDictionary <string, object> >, KeyValuePair <string, IReadOnlyDictionary <string, object> > > mapFunc = null) { switch (joinDefinition.Type) { case JoinType.Inner: var innerJoin = from lefts in leftEntities join rights in rightEntities on lefts.Value[joinDefinition.Left.JoinedFieldName] equals rights.Value[joinDefinition.Right.JoinedFieldName] into joined from result in joined select mapFunc?.Invoke(lefts, result) ?? lefts; return(innerJoin .Select(e => EntityFromContainerProperties(e.Value, metadata)) .ToList()); case JoinType.Left: var leftJoin = from lefts in leftEntities join rights in rightEntities on lefts.Value[joinDefinition.Left.JoinedFieldName] equals rights.Value[joinDefinition.Right.JoinedFieldName] into joined from result in joined.DefaultIfEmpty() select mapFunc?.Invoke(lefts, result) ?? lefts; return(leftJoin .Select(e => EntityFromContainerProperties(e.Value, metadata)) .ToList()); default: throw new ArgumentOutOfRangeException(nameof(JoinType)); } }
private void VerifyConcurrencyCheck(TAggregateRoot aggregate) { var streamName = GetEventStreamName(aggregate.Id); var eventContainerName = GetEventContainerName(); var query = Query.From <EntityEvent>().Where(ee => ee.StreamName, ConditionOperator.EqualTo, streamName) .OrderBy(ee => ee.Version).Take(1); var latestEvent = this.repository .Query(eventContainerName, query, RepositoryEntityMetadata.FromType <EntityEvent>()) .FirstOrDefault(); var latestStoredVersion = latestEvent == null ? 0 : latestEvent.ToEntity <EntityEvent>(this.domainFactory).Version; var loadedVersion = aggregate.ChangeVersion; if (latestStoredVersion > loadedVersion) { throw new ResourceConflictException( Resources.GeneralEventStreamStorage_LoadConcurrencyConflictWritingEventStream.Fmt(streamName, loadedVersion)); } }
private static QueryEntity EntityFromContainerProperties( this IReadOnlyDictionary <string, object> propertyValues, RepositoryEntityMetadata metadata) { return(QueryEntity.FromProperties(propertyValues, metadata)); }
public TAggregateRoot Load(Identifier id, bool returnNullIfNotFound = false) { id.GuardAgainstNull(nameof(id)); var streamName = GetEventStreamName(id); var eventContainerName = GetEventContainerName(); var events = this.repository.Query(eventContainerName, Query.From <EntityEvent>() .Where(ee => ee.StreamName, ConditionOperator.EqualTo, streamName) .OrderBy(ee => ee.LastPersistedAtUtc), RepositoryEntityMetadata.FromType <EntityEvent>()); if (!events.Any()) { return(returnNullIfNotFound ? default : RehydrateAggregateRoot(id, null)); } var lastPersistedAtUtc = events.Last().LastPersistedAtUtc; var aggregate = RehydrateAggregateRoot(id, lastPersistedAtUtc); aggregate.LoadChanges(events.ConvertAll(@event => @event.ToEntity <EntityEvent>(this.domainFactory)), this.migrator); return(aggregate); }
private static string FirstProperty <TQueryableEntity>() where TQueryableEntity : IQueryableEntity { var metadata = RepositoryEntityMetadata.FromType <TQueryableEntity>(); return(metadata.Types.First().Key); }
private static bool HasProperty <TQueryableEntity>(string propertyName) where TQueryableEntity : IQueryableEntity { var metadata = RepositoryEntityMetadata.FromType <TQueryableEntity>(); return(metadata.HasType(propertyName)); }
public static List <QueryEntity> FetchAllIntoMemory <TQueryableEntity>(this QueryClause <TQueryableEntity> query, IRepository repository, RepositoryEntityMetadata metadata, Func <Dictionary <string, IReadOnlyDictionary <string, object> > > getPrimaryEntities, Func <QueriedEntity, Dictionary <string, IReadOnlyDictionary <string, object> > > getJoinedEntities) where TQueryableEntity : IQueryableEntity { repository.GuardAgainstNull(nameof(repository)); query.GuardAgainstNull(nameof(query)); metadata.GuardAgainstNull(nameof(metadata)); getPrimaryEntities.GuardAgainstNull(nameof(getPrimaryEntities)); getJoinedEntities.GuardAgainstNull(nameof(getJoinedEntities)); var take = query.GetDefaultTake(repository); if (take == 0) { return(new List <QueryEntity>()); } var primaryEntities = getPrimaryEntities(); if (!primaryEntities.HasAny()) { return(new List <QueryEntity>()); } var joinedContainers = query.JoinedEntities .Where(je => je.Join.Exists()) .ToDictionary(je => je.EntityName, je => new { Collection = getJoinedEntities(je), JoinedEntity = je }); List <KeyValuePair <string, IReadOnlyDictionary <string, object> > > joinedEntities = null; if (!joinedContainers.Any()) { joinedEntities = primaryEntities .Select(pe => new KeyValuePair <string, IReadOnlyDictionary <string, object> >(pe.Key, pe.Value)) .ToList(); } else { foreach (var joinedContainer in joinedContainers) { var joinedEntity = joinedContainer.Value.JoinedEntity; var join = joinedEntity.Join; var rightEntities = joinedContainer.Value.Collection .ToDictionary(e => e.Key, e => e.Value); joinedEntities = join .JoinResults(primaryEntities, rightEntities, joinedEntity.Selects.ProjectSelectedJoinedProperties()); } } var results = joinedEntities?.AsQueryable(); var orderBy = query.ToDynamicLinqOrderByClause(); var skip = query.GetDefaultSkip(); if (query.Wheres.Any()) { var whereBy = query.Wheres.ToDynamicLinqWhereClause(); results = results .Where(whereBy); } return(results .OrderBy(orderBy) .Skip(skip) .Take(take) .Select(sel => new KeyValuePair <string, IReadOnlyDictionary <string, object> >(sel.Key, sel.Value)) .CherryPickSelectedProperties(query) .Select(ped => QueryEntity.FromProperties(ped.Value, metadata)) .ToList()); }