从 Microsoft.Azure.Cosmos.Table 迁移到 Azure.Data.Tables 后,UpsertEntityAsync 抛出错误

问题描述 投票:0回答:1

我正在将包含 Microsoft.Azure.Cosmos.Table 的现有项目迁移到 Azure.Data.Tables。我遵循迁移指南并使用

ITableEntity

实现了我的自定义模型

带有宇宙的插入物看起来像

private async Task InsertOrMergeAsync(CloudTable table, OfficeSupplyEntity record)
{
    var insertOrMergeOperation = TableOperation.InsertOrMerge(record);
    await table.ExecuteAsync(insertOrMergeOp);
}

迁移后,它转换为

    private async Task InsertOrMergeAsync(TableClient table, OfficeSupplyEntity record)
    {
        await table.UpsertEntityAsync(record);
    }

但现在我收到错误

An error occurred while processing this request.
RequestId:915023cb-f88d-47c3-81f0-1debbf39c8ef
Time:2024-12-19T07:26:55.088Z
Status: 400 (Bad Request)
ErrorCode: InvalidInput

Content:
{"odata.error":{"code":"InvalidInput","message":{"lang":"en-US","value":"An error occurred while processing this request.\nRequestId:915023cb-f88d-47c3-81f0-1debbf39c8ef\nTime:2024-12-19T07:26:55.088Z"}}}

Headers:
Server: Azurite-Table/3.33.0
x-ms-error-code: REDACTED
x-ms-request-id: 915023cb-f88d-47c3-81f0-1debbf39c8ef
x-ms-version: REDACTED
Date: Thu, 19 Dec 2024 07:26:55 GMT
Connection: keep-alive
Keep-Alive: REDACTED
Transfer-Encoding: chunked
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8

在指南中,this部分也不清楚

下面直接引用

之前在

Microsoft.Azure.Cosmos.Table
中,我们将创建一个
TableOperation
并使用表客户端执行它。 操作结果必须转换回实体类型。

// Create the InsertOrReplace table operation
TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(entity);

// Execute the operation.
TableResult result = cloudTable.Execute(insertOrMergeOperation);

// Cast the result.
OfficeSupplyOld insertedCustomer = result.Result as OfficeSupplyOld;

现在在

Azure.Data.Tables
中,使用
TableClient
,我们可以简单地将实体传递给
UpsertEntity
方法,该方法将根据是否创建或更新实体 或者它已经存在。

// Upsert the newly created entity.
tableClient.UpsertEntity(tableEntity);

指南中的什么是

tableEntity
?和
entity
有什么不同吗?

c# .net azure azure-cosmosdb azure-table-storage
1个回答
0
投票

从 Microsoft.Azure.Cosmos.Table 迁移到 Azure.Data.Tables 后,UpsertEntityAsync 抛出错误

tableEntity
entity
不同,其中 tableEntity 是 Azure 表存储中实体属性的灵活容器,而 entity 是代码中用于表示表实体的 instance 的变量。

由于 Azure 数据表不支持存储数组,因此会引发错误。尝试使用以下代码在 Azure 数据表中存储数组。它使用序列化器

JsonSerializer.Serialize
将数组转换为 JSON 字符串,这允许数组作为单个属性存储在 Azure 表存储中。现在使用
JsonSerializer.Deserialize
进行反序列化,以便将 JSON 字符串反序列化为数组。

class TableStorageArray
{
    private const string storageAccountName = "<accName>";  
    private const string storageAccountKey = "<primaryKey>";  
    private const string tableName = "TableB";

    private async Task InsertOrMergeAsync(TableClient tableClient, Azure.Data.Tables.TableEntity record)
    {
        await tableClient.UpsertEntityAsync(record, TableUpdateMode.Merge);
    }

    private async Task InsertOrMergeAsync(CosmosTable.CloudTable table, CosmosTable.DynamicTableEntity record)
    {
        var operation = CosmosTable.TableOperation.InsertOrMerge(record);
        await table.ExecuteAsync(operation);
    }

    private async Task StorageAsync()
    {
        string connectionString = $"DefaultEndpointsProtocol=https;AccountName={storageAccountName};AccountKey={storageAccountKey};EndpointSuffix=core.windows.net";

        var tableClient = new TableServiceClient(connectionString).GetTableClient(tableName);
        await tableClient.CreateIfNotExistsAsync();

        var storageAccount = CosmosTable.CloudStorageAccount.Parse(connectionString);
        var table = storageAccount.CreateCloudTableClient().GetTableReference(tableName);
        await table.CreateIfNotExistsAsync();

        Console.WriteLine("Table connected or created.");

        var partitionKey = "1";
        var rowKey = "1";
        var arrayField = new[] { "Value1", "Value6", "Value9" };
        var arrayAsJson = JsonSerializer.Serialize(arrayField);

        var recordForTableClient = new Azure.Data.Tables.TableEntity(partitionKey, rowKey)
        {
            { "Name", "Sai Paul" },
            { "ArrayField", arrayAsJson }
        };

        var recordForCloudTable = new CosmosTable.DynamicTableEntity(partitionKey, rowKey)
        {
            Properties = {
                { "Name", new CosmosTable.EntityProperty("Sai Paul") },
                { "ArrayField", new CosmosTable.EntityProperty(arrayAsJson) }
            }
        };

        await InsertOrMergeAsync(tableClient, recordForTableClient);

        await InsertOrMergeAsync(table, recordForCloudTable);

        var retrievedEntity = await tableClient.GetEntityAsync<Azure.Data.Tables.TableEntity>(partitionKey, rowKey);
        string retrievedJson = retrievedEntity.Value.GetString("ArrayField");
        var deserializedArray = JsonSerializer.Deserialize<string[]>(retrievedJson);

        Console.WriteLine("Deserialized Array:");
        foreach (var item in deserializedArray)
        {
            Console.WriteLine(item);
        }
    }

    static async Task Main(string[] args)
    {
        try
        {
            var example = new TableStorageArray();
            await example.StorageAsync();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

输出:

Table connected or created.
Deserialized Array:
Value1
Value6
Value9
© www.soinside.com 2019 - 2024. All rights reserved.