TableResult зависает при извлечении существующего элемента таблицы Azure - PullRequest
0 голосов
/ 21 апреля 2020

Я использую Azure Таблицы для выполнения операций CRUD с конкретным объектом. Я могу вставить правильно, используя этот код:

public async Task CreateOrUpdate(UserCredentials data)
    {
        if (data == null)
        {
            throw new ArgumentNullException("data");
        }

        await _cloudTable.CreateIfNotExistsAsync();

        var result = Get(data.RowKey).Result;

        if (result != null)
        {
            result.Username = data.Username;
            result.FailedAttempts += 1;

            var retrieveOperation = TableOperation.Replace(result);
            await _cloudTable.ExecuteAsync(retrieveOperation);
        }
        else
        {
            data.CreatedOn = DateTime.Now;
            data.FailedAttempts = data.LoginFailed ? 1 : 0;
            TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(data);
            await _cloudTable.ExecuteAsync(insertOrMergeOperation);
        }
    }

Первый раз, когда элемент не существует в Azure Таблицах, но как только у меня есть элементы в таблице, функция Get не работает. Он зависает при выполнении операции:

public async Task<UserCredentials> Get(string key)
    {
        await _cloudTable.CreateIfNotExistsAsync();

        TableOperation retrieve = TableOperation.Retrieve<UserCredentials>(nameof(UserCredentials), key);

        TableResult result = await _cloudTable.ExecuteAsync(retrieve);  <-- It never comes back from here

        return result.Result as UserCredentials;
    }

Это мой объект Entity:

public class UserCredentials : TableEntity
{
    public string Username { get; set; }
    public string PasswordHash { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ExpiresOn { get; set; }
    public int FailedAttempts { get; set; }
    public bool LoginFailed { get; set; }


    public UserCredentials(string username)
    {
        PartitionKey = nameof(UserCredentials);
        RowKey = username;
    }
}

Так что мой await _cloudTable.ExecuteAsync(retrieve); никогда не возвращается, когда передается существующий rowKey. Но он отлично работает, если таблица пуста (поэтому вставка работает нормально, но не извлекает из существующего rowKey).

Есть идеи, почему она не возвращается?

1 Ответ

1 голос
/ 21 апреля 2020

Мне удалось воспроизвести эту проблему.

Чтобы это исправить, добавьте конструктор без параметров для вашей сущности.

public class UserCredentials : TableEntity
{
    public string Username { get; set; }
    public string PasswordHash { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ExpiresOn { get; set; }
    public int FailedAttempts { get; set; }
    public bool LoginFailed { get; set; }

    public UserCredentials()
    {

    }

    public UserCredentials(string username)
    {
        PartitionKey = nameof(UserCredentials);
        RowKey = username;
    }
}
...