具有Complex属性的Azure TableStorage实体



我试图获得一个HashSet<string>到Azure表存储。我想模型项目的成员:

public class DbProject : ITableEntity {
public string Name { get; set; } = default!;
public string Owner { get; set; } = default!;
public HashSet<string> Members { get; set; } = default!;
public DateTime CreatedOn { get; set; } = default!;
public string PartitionKey { get; set; } = default!;
public string RowKey { get;set; } = default!;
public DateTimeOffset? Timestamp { get;set; } = default!;
public ETag ETag { get;set; } = default!;
}

"插入逻辑"看起来像:

var dbProject = new DbProject {
Name = projectName,
Owner = owner,
CreatedOn = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc),
Members = new HashSet<string> { owner },
PartitionKey = $"{owner}__{projectName}",
RowKey = $"{owner}__{projectName}"
};
try {
this.tableClient.AddEntity<DbProject>(dbProject);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}

得到的错误是:

ErrorCode: InvalidInput
Content:
{"odata.error":{"code":"InvalidInput","message":{"lang":"en-US","value":"An error occurred while processing this request.nRequestId:6019edb7-c002-001c-1be9-bd1379000000nTime:2021-10-10T15:15:24.5069601Z"}}}

如果我删除HashSet,它就像一个魅力,所以我猜在Azure表存储中创建记录时使用复杂类型有问题。

我想运行简单的查询,如:

public bool IsMember(string owner, string projectName) {
var query = TableClient.CreateQueryFilter<DbProject>(u => u.Name == projectName && u.Members.Contains(owner));
return tableClient.Query<DbProject>(query).Any();
}

既然您在评论中要求提供替代解决方案:最明显的选择是使用CosmosDB而不是表存储。在许多场景中,表存储非常有限。如果您出于特定原因不需要使用表存储,则建议在新项目中使用CosmosDB和SQL API。

正如Jeremy的评论中提到的,你可以在那里使用HashSet:如何在复杂的JSON对象中搜索Cosmos DB

如果你想保留表存储,而不需要对你的HashSet进行查询:你可以像Gaurav提到的那样将你的HashSet序列化为字符串。也许像这样:

[IgnoreProperty]
public HashSet<string> Members { get; set; }
public override void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
{
Members = JsonConvert.DeserializeObject<HashSet<string>>(properties[nameof(Members)].StringValue);
}
public override IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
{
var properties = new Dictionary<string, EntityProperty>();
properties.Add(nameof(Members), new EntityProperty(JsonConvert.SerializeObject(Members)));
return properties;
}

你也可以看看这个:添加一个TableEntity的复杂属性到Azure表存储

你遇到这个问题的原因是因为Azure表存储不支持复杂的数据类型(HashSet是其中之一)。

有关支持的数据类型列表,请参阅此链接:https://learn.microsoft.com/en-us/rest/api/storageservices/understanding-the-table-service-data-model#property-types。

您需要做的是将复杂的数据类型序列化为一种支持的数据类型(string数据类型是最合适的)并保存它。当你读取数据时,你必须反序列化它。请注意,这样做你将失去的能力在这个特定的查询属性。

相关内容

  • 没有找到相关文章

最新更新