Пример #1
0
        private static async Task ProcessSavesAsync(
            List <EntityInfo> saveOrder,
            PersistenceManager persistenceManager,
            SaveChangesContext context,
            ISaveChangesOptions saveChangesOptions,
            ConfiguredSessionProvider sessionProvider, CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            foreach (var entityInfo in saveOrder)
            {
                await(persistenceManager.BeforeSaveEntityChangesAsync(entityInfo, context, cancellationToken)).ConfigureAwait(false);
                var beforeSaveEntityChangesTask = saveChangesOptions?.BeforeSaveEntityChangesAsync(entityInfo, context, cancellationToken);
                if (beforeSaveEntityChangesTask != null)
                {
                    await(beforeSaveEntityChangesTask).ConfigureAwait(false);
                }

                var session = sessionProvider.GetSession(entityInfo.EntityType);
                try
                {
                    switch (entityInfo.EntityState)
                    {
                    case EntityState.Modified:
                        await(session.UpdateAsync(entityInfo.Entity, cancellationToken)).ConfigureAwait(false);
                        break;

                    case EntityState.Added:
                        await(session.SaveAsync(entityInfo.Entity, cancellationToken)).ConfigureAwait(false);
                        break;

                    case EntityState.Deleted:
                        await(session.DeleteAsync(entityInfo.Entity, cancellationToken)).ConfigureAwait(false);
                        break;
                    }
                }
                catch (PropertyValueException e)
                {
                    // NH can throw this when a not null property is null or transient (e.g. not-null property references a null or transient value)
                    var errors = new[]
                    {
                        // KeyValues cannot be determined as the exception may reference another entity
                        new EntityError
                        {
                            EntityTypeName = e.EntityName,
                            ErrorMessage   = e.Message,
                            ErrorName      = "PropertyValueException",
                            PropertyName   = e.PropertyName
                        }
                    };

                    throw new EntityErrorsException(e.Message, errors);
                }
            }
        }
Пример #2
0
 private static Task <object> LoadEntityAsync(Type entityType, object id, ConfiguredSessionProvider sessionProvider, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (cancellationToken.IsCancellationRequested)
     {
         return(Task.FromCanceled <object>(cancellationToken));
     }
     try
     {
         var session = sessionProvider.GetSession(entityType);
         return(session.LoadAsync(entityType, id, cancellationToken));
     }
     catch (Exception ex)
     {
         return(Task.FromException <object>(ex));
     }
 }
Пример #3
0
        private async Task RefreshFromSessionAsync(Dictionary <Type, List <EntityInfo> > saveMap, ConfiguredSessionProvider sessionProvider, CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            foreach (var pair in saveMap)
            {
                var modelConfiguration = _breezeConfigurator.GetModelConfiguration(pair.Key);
                if (modelConfiguration.RefreshAfterSave != true && modelConfiguration.RefreshAfterUpdate != true)
                {
                    continue;
                }

                var session = sessionProvider.GetSession(pair.Key);
                foreach (var entityInfo in pair.Value)
                {
                    if (entityInfo.EntityState == EntityState.Added && modelConfiguration.RefreshAfterSave == true ||
                        entityInfo.EntityState == EntityState.Modified && modelConfiguration.RefreshAfterUpdate == true)
                    {
                        await(session.RefreshAsync(entityInfo.Entity, cancellationToken)).ConfigureAwait(false);
                    }
                }
            }
        }
Пример #4
0
        private async Task SetupDatabaseEntitiesAsync(Type entityType,
                                                      List <EntityInfo> entitiesInfo,
                                                      Dictionary <Type, List <EntityInfo> > saveMap,
                                                      EntityIdMap entitiesIdMap,
                                                      ConfiguredSessionProvider sessionProvider, CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            var modelConfiguration = _breezeConfigurator.GetModelConfiguration(entityType);
            var metadata           = _entityMetadataProvider.GetMetadata(entityType);

            if (metadata.ManyToOneIdentifierProperties.Count > 0)
            {
                await(SetupManyToOneIdentifierPropertiesAsync(entitiesInfo, saveMap, true, sessionProvider, cancellationToken)).ConfigureAwait(false);
            }

            var session     = sessionProvider.GetSession(entityType);
            var batchSize   = modelConfiguration.BatchFetchSize ?? session.GetSessionImplementation().Factory.Settings.DefaultBatchFetchSize;
            var persister   = metadata.EntityPersister;
            var existingIds = entitiesInfo.Where(o => o.EntityState != EntityState.Added)
                              .Select(o => persister.GetIdentifier(o.ClientEntity))
                              .ToList();
            var batchFetcher = metadata.BatchFetcher;
            var dbEntities   = existingIds.Count > 0 ? await(batchFetcher.BatchFetchAsync(session, existingIds, batchSize, cancellationToken)).ConfigureAwait(false) : null;

            var idMap = entitiesIdMap.GetTypeIdMap(entityType, entitiesInfo.Count);

            foreach (var entityInfo in entitiesInfo)
            {
                foreach (var identifierPropertyName in metadata.IdentifierPropertyNames)
                {
                    if (entityInfo.OriginalValuesMap.ContainsKey(identifierPropertyName))
                    {
                        var errors = new[]
                        {
                            new EntityError
                            {
                                EntityTypeName = entityInfo.EntityType.FullName,
                                ErrorMessage   = "Cannot update part of the entity's key",
                                ErrorName      = "KeyUpdateException",
                                KeyValues      = entityInfo.GetIdentifierValues(),
                                PropertyName   = identifierPropertyName
                            }
                        };

                        throw new EntityErrorsException("Cannot update part of the entity's key", errors);
                    }
                }

                var    id = persister.GetIdentifier(entityInfo.ClientEntity);
                object dbEntity;
                if (entityInfo.EntityState == EntityState.Added)
                {
                    dbEntity = metadata.CreateInstance();
                    if (metadata.AutoGeneratedKeyType != AutoGeneratedKeyType.Identity &&
                        !(persister.IdentifierGenerator is ForeignGenerator))
                    {
                        if (metadata.ManyToOneIdentifierProperties.Count > 0)
                        {
                            await(SetManyToOneIdentifierAsync(entityInfo, dbEntity, saveMap, false, sessionProvider, cancellationToken)).ConfigureAwait(false);
                        }
                        else
                        {
                            persister.SetIdentifier(dbEntity, id);
                        }
                    }
                }
                else if (dbEntities == null || !dbEntities.TryGetValue(id, out dbEntity) || dbEntity == null)
                {
                    throw new InvalidOperationException($"Entity {entityType} with id {id} was not found.");
                }

                entityInfo.Entity = dbEntity;
                idMap.Add(id, entityInfo);
                entitiesIdMap.AddToDerivedTypes(entityInfo, id, entitiesInfo.Count);
            }
        }