我在Azure表中存储了一些这样的枚举
pk rk | en fr de ...
foo 1 | 'Eune' 'Fune' 'Dune' ...
foo 2 | 'Edoe' 'Fdoe' 'Ddoe' ...
bar 1 | 'Unee' 'Unef' 'Trid' ...
bar 2 | 'Diee' 'Dief' 'Died' ...
bar 3 | 'Trie' 'Tref' 'Trid' ...
en
,fr
,de
等...是语言代码,分别是表格中的列名称。
我应该创建哪种TableEntity
才能正确加载
public class FooEntity : TableEntity
{
public Dictionary<string, string> Descriptions {get; set} // ?
}
然后像myFoo["fr"]
一样使用它们......有可能吗?
假设我有英文GUI,我需要显示Foo
选择Eune
/ Edoe
作为选择值。
答案 0 :(得分:6)
我的回答扩展了Zhaoxing将复杂实体属性编写为JSON并将其持久保存到Azure CosmosDB的方法。
但是,setter中字符串和对象之间的序列化会导致以下问题:
相反,我重写了TableEntity的WriteEntity和ReadEntity方法来编写自定义序列化和反序列化代码,只有在从CloudTable检索实体或将其提交给它时才会调用 - 因此每次检索只执行一次更新操作等
以下代码。我已经说明了一个更复杂的例子,其中我的TableEntity包含一个类,而该类又包含一个字典。
public class MeetingLayoutEntity : TableEntity
{
/// <summary>
/// Extends TableEntity, the base class for entries in Azure CosmosDB Table tables.
/// </summary>
public MeetingLayoutEntity() { }
public MeetingLayoutEntity(MeetingLayout layout, string partition, string meetingId)
{
this.Layout = layout;
this.PartitionKey = partition;
this.RowKey = meetingId;
}
// Complex object which will be serialized/persisted as a JSON.
[IgnoreProperty]
public MeetingLayout Layout { get; set; }
public override IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
{
// This line will write partition key and row key, but not Layout since it has the IgnoreProperty attribute
var x = base.WriteEntity(operationContext);
// Writing x manually as a serialized string.
x[nameof(this.Layout)] = new EntityProperty(JsonConvert.SerializeObject(this.Layout));
return x;
}
public override void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
{
base.ReadEntity(properties, operationContext);
if (properties.ContainsKey(nameof(this.Layout)))
{
this.Layout = JsonConvert.DeserializeObject<MeetingLayout>(properties[nameof(this.Layout)].StringValue);
}
}
}
详细了解ReadEntity和WriteEntity。
答案 1 :(得分:5)
Azure存储表不支持将Array,List或Dictionary作为实体属性。您可以找到所有支持的属性类型here(“属性类型”部分)。
但是,您可以考虑将数组/列表/字典序列化为字符串属性,并在TableEntity类中使用[IgnoreProperty]属性声明一个属性,以将序列化字符串转换回数组/列表/字典。
public class MyEntity : TableEntity
{
public string DicPropertyRaw { get; set; }
[IgnoreProperty]
public Dictionary<string, string> DicProperty
{
get
{
return Deserialize(DicPropertyRaw);
}
set
{
DicPropertyRaw = Serialize(value);
}
}
}
答案 2 :(得分:0)
您可以使用ObjectFlattenerRecomposer api Nuget包将任何类型的对象写入表存储: https://www.nuget.org/packages/ObjectFlattenerRecomposer/版本2.0.0还支持数组和枚举。这些属性将在写入表存储之前透明地转换为json字符串,并在从表存储中读取时反序列化为原始对象。该API还允许您将复杂对象也写入表存储。
答案 3 :(得分:0)
此解决方案具有以下优点:
[IgnoreProperty]
时不会具有两个)。此解决方案在以下网站上有详细说明: https://www.devprotocol.com/azure-table-storage-and-complex-types-stored-in-json/
Github回购: https://github.com/jtourlamain/DevProtocol.Azure.EntityPropertyConverter
如果您希望使用LINQ的解决方案: https://blog.bitscry.com/2019/04/12/adding-complex-properties-of-a-tableentity-to-azure-table-storage/
更好的方法是,使用最新的库以正确的方式进行操作,并使用内置的Flatten和ConvertBack:https://stackoverflow.com/a/35068938/1785972