/// <summary> /// Queue a new operation /// </summary> /// <typeparam name="T">Type of businessObject</typeparam> /// <param name="businessObject">Business object instance - cannot be NULL.</param> /// <param name="type">Type of TableOperation to generate</param> public void Add <T>(T businessObject, TableOperationType type) where T : class { if (_isDraining) { // no items can be added during a drain throw new Exception("Cannot queue items during a drain."); } if (businessObject == null) { throw new ArgumentNullException("businessObject"); } TableOperation operation = type switch { TableOperationType.Delete => TableOperation.Delete(AzureTableEntity.From(businessObject, forDelete: true)), TableOperationType.Insert => TableOperation.Insert(AzureTableEntity.From(businessObject)), TableOperationType.InsertOrMerge => TableOperation.InsertOrMerge(AzureTableEntity.From(businessObject)), TableOperationType.InsertOrReplace => TableOperation.InsertOrReplace(AzureTableEntity.From(businessObject)), TableOperationType.Merge => TableOperation.Merge(AzureTableEntity.From(businessObject)), TableOperationType.Replace => TableOperation.Replace(AzureTableEntity.From(businessObject)), _ => throw new ArgumentOutOfRangeException("Unsupported operation for queue!") }; _queueOrder.Enqueue(_queueIndex); _queue.TryAdd(_queueIndex++, new TableOperationWrapper(operation, AzureTablesDataSource.GetTableName <T>())); }
/// <summary> /// Queue a new operation /// </summary> /// <typeparam name="T">Type of businessObject</typeparam> /// <param name="listOfObjects">Business object instances - cannot be NULL.</param> /// <param name="type">Type of TableBatchOperation to generate</param> public void Add <T>(IEnumerable <T> listOfObjects, TableOperationType type) where T : class { if (_isDraining) { // no items can be added during a drain throw new Exception("Cannot queue items during a drain."); } if (listOfObjects == null) { throw new ArgumentNullException(nameof(listOfObjects)); } int t = (int)type; // these are the int values of the range of operation types supported if ((t < 0) || (t > 5)) { throw new ArgumentOutOfRangeException("Unsupported operation for queue!"); } string currentPartitionKey = Guid.NewGuid().ToString(); // nobody's partition key will ever be the same as this! string tableName = AzureTablesDataSource.GetTableName <T>(); string operationName = Enum.GetName(typeof(TableOperationType), type) ?? "Unknown"; TableBatchOperation batch = new TableBatchOperation(); foreach (T obj in listOfObjects) { TableOperation tableOperation = type switch { TableOperationType.Delete => TableOperation.Delete(AzureTableEntity.From(obj, forDelete: true)), TableOperationType.Insert => TableOperation.Insert(AzureTableEntity.From(obj)), TableOperationType.InsertOrMerge => TableOperation.InsertOrMerge(AzureTableEntity.From(obj)), TableOperationType.InsertOrReplace => TableOperation.InsertOrReplace(AzureTableEntity.From(obj)), TableOperationType.Merge => TableOperation.Merge(AzureTableEntity.From(obj)), TableOperationType.Replace => TableOperation.Replace(AzureTableEntity.From(obj)) // Actually redundant, since this is already checked at the top of the function. , _ => throw new ArgumentOutOfRangeException($"Unsupported operation '{operationName}'") }; // all items in a batch must be the same partition key // so if we hit a different one, we jump to a new batch if ((batch.Count > 0) && (tableOperation.Entity.PartitionKey != currentPartitionKey)) { _queue.Enqueue(new TableBatchOperationWrapper(batch, tableName)); batch = new TableBatchOperation(); currentPartitionKey = tableOperation.Entity.PartitionKey; } else if (batch.Count == 0) { currentPartitionKey = tableOperation.Entity.PartitionKey; } batch.Add(tableOperation); if (batch.Count == __MAX_ITEMS_PER_BATCH) { _queue.Enqueue(new TableBatchOperationWrapper(batch, tableName)); batch = new TableBatchOperation(); } ItemAdded?.Invoke(tableName, operationName, currentPartitionKey, tableOperation.Entity.RowKey); } // flush remaining entities to the queue if (batch.Count > 0) { _queue.Enqueue(new TableBatchOperationWrapper(batch, tableName)); } }