public virtual T Merge(string partitionKey, string rowKey, Func <T, T> replaceAction)
        {
            object itm = "Not read";

            try
            {
                while (true)
                {
                    try
                    {
                        var entity = this[partitionKey, rowKey];
                        if (entity != null)
                        {
                            itm = entity;
                            var result = replaceAction(entity);
                            if (result != null)
                            {
                                GetTable().Execute(TableOperation.Merge(result));
                            }
                        }
                    }
                    catch (StorageException e)
                    {
                        // Если поймали precondition fall = 412, значит в другом потоке данную сущность успели поменять
                        // - нужно повторить операцию, пока не исполнится без ошибок
                        if (e.RequestInformation.HttpStatusCode != 412)
                        {
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _log?.WriteFatalError("Table storage: " + _tableName, "Merge item", AzureStorageUtils.PrintItem(itm), ex);
                throw;
            }
        }
        private IEnumerable <T> ExecuteQuery(string processName, TableQuery <T> rangeQuery, Func <T, bool> filter)
        {
            TableContinuationToken tableContinuationToken = null;

            do
            {
                TableQuerySegment <T> queryResponse;
                try
                {
                    queryResponse          = GetTable().ExecuteQuerySegmented(rangeQuery, tableContinuationToken);
                    tableContinuationToken = queryResponse.ContinuationToken;
                }
                catch (Exception ex)
                {
                    _log?.WriteFatalError("Table storage: " + _tableName, processName, rangeQuery.FilterString ?? "[null]", ex);
                    throw;
                }

                foreach (var itm in AzureStorageUtils.ApplyFilter(queryResponse.Results, filter))
                {
                    yield return(itm);
                }
            } while (tableContinuationToken != null);
        }
        /// <summary>
        /// Выполнить запрос асинхроно
        /// </summary>
        /// <param name="processName">Имя процесса (для лога)</param>
        /// <param name="rangeQuery">Параметры запроса</param>
        /// <param name="filter">Фильтрация запроса</param>
        /// <param name="yieldData">Данные которые мы выдаем наружу. Если возвращается false - данные можно больше не запрашивать</param>
        /// <returns></returns>
        private async Task ExecuteQueryAsync(string processName, TableQuery <T> rangeQuery, Func <T, bool> filter, Func <IEnumerable <T>, bool> yieldData)
        {
            try
            {
                TableContinuationToken tableContinuationToken = null;
                var table = GetTable();
                do
                {
                    var queryResponse = await table.ExecuteQuerySegmentedAsync(rangeQuery, tableContinuationToken);

                    tableContinuationToken = queryResponse.ContinuationToken;
                    var shouldWeContinue = yieldData(AzureStorageUtils.ApplyFilter(queryResponse.Results, filter));
                    if (!shouldWeContinue)
                    {
                        break;
                    }
                }while (tableContinuationToken != null);
            }
            catch (Exception ex)
            {
                _log?.WriteFatalError("Table storage: " + _tableName, processName, rangeQuery.FilterString ?? "[null]", ex).Wait();
                throw;
            }
        }
        public virtual void CreateIfNotExists(T item)
        {
            try
            {
                if (!RecordExists(item))
                {
                    InsertOrReplace(item);
                }
            }
            catch (Exception ex)
            {
                _log?.WriteFatalError("Table storage: " + _tableName, "Create if not exists", AzureStorageUtils.PrintItem(item), ex);

                throw;
            }
        }
 public Task DeleteAsync(IEnumerable <T> items)
 {
     items = items.ToArray();
     try
     {
         if (items.Any())
         {
             var deleteBatchOperation = new TableBatchOperation();
             foreach (var item in items)
             {
                 deleteBatchOperation.Delete(item);
             }
             return(GetTable().ExecuteBatchAsync(deleteBatchOperation));
         }
     }
     catch (Exception ex)
     {
         _log?.WriteFatalError("Table storage: " + _tableName, "DeleteAsync batch", AzureStorageUtils.PrintItems(items), ex);
     }
     return(Task.CompletedTask);
 }
 public virtual async Task InsertOrReplaceAsync(T item)
 {
     try
     {
         await GetTable().ExecuteAsync(TableOperation.InsertOrReplace(item));
     }
     catch (Exception ex)
     {
         _log?.WriteFatalError("Table storage: " + _tableName, "InsertOrReplace item", AzureStorageUtils.PrintItem(item),
                               ex).Wait();
         throw;
     }
 }
        public async Task <T> MergeAsync(string partitionKey, string rowKey, Func <T, T> mergeAction)
        {
            object itm = "Not read";

            try
            {
                while (true)
                {
                    try
                    {
                        var entity = await GetDataAsync(partitionKey, rowKey);

                        if (entity != null)
                        {
                            var result = mergeAction(entity);
                            itm = result;
                            if (result != null)
                            {
                                await GetTable().ExecuteAsync(TableOperation.Merge(result));
                            }

                            return(result);
                        }
                        return(null);
                    }
                    catch (StorageException e)
                    {
                        // Если поймали precondition fall = 412, значит в другом потоке данную сущность успели поменять
                        // - нужно повторить операцию, пока не исполнится без ошибок
                        if (e.RequestInformation.HttpStatusCode != 412)
                        {
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _log?.WriteFatalError("Table storage: " + _tableName, "Replace item", AzureStorageUtils.PrintItem(itm), ex).Wait();
                throw;
            }
        }
 public async Task InsertOrMergeAsync(T item)
 {
     try
     {
         await GetTable().ExecuteAsync(TableOperation.InsertOrMerge(item));
     }
     catch (Exception ex)
     {
         if (_log != null)
         {
             await _log.WriteFatalError("Table storage: " + _tableName, "InsertOrMerge item", AzureStorageUtils.PrintItem(item), ex);
         }
     }
 }
 public virtual void InsertOrMerge(T item)
 {
     try
     {
         GetTable().Execute(TableOperation.InsertOrMerge(item));
     }
     catch (Exception ex)
     {
         _log?.WriteFatalError("Table storage: " + _tableName, "InsertOrMerge item", AzureStorageUtils.PrintItem(item),
                               ex);
     }
 }