是否可以为Azure表存储提供非派生POCO ?
换句话说,POCO既不是源自TableEntity
,也不是实现ITableEntity
?
必须有一个依赖于接口或基类的模型似乎是一种倒退,因为这会导致链中的引用向上泄漏——如果不知道接口或基类的Azure存储,我无法在另一层中设置模型!
看看DynamicTableEntity
(ctrl+f)。它可用于查询和插入实体。
使用这种类型,你不会在你的领域模型中引入任何依赖关系,但是你必须自己将POCO转换为DynamicTableEntity——如果你愿意用自定义接口标记POCO并编写映射器,这个过程可以很容易地自动化(基本上你只需要一个属性字典+需要知道哪些是Partition/RowKey)。
你不能在Azure表存储中保存任何实体的原因是它需要知道哪个属性作为分区键,哪个作为行键。必须在"较低级别"上使用DynamicTableEntity
的好处是,您可以创建只返回属性子集的查询,从而减少资源消耗。
看一下我实现并放入Nuget的包:https://www.nuget.org/packages/ObjectFlattenerRecomposer/
它也被添加到Azure存储SDK的下一个版本:https://github.com/Azure/azure-storage-net/pull/337/files
描述:
提供将复杂对象扁平化到EntityProperty字典中的功能,以及从扁平化的属性字典中重新组合原始复杂对象的功能。一个用法是API允许以扁平的形式将任何具有嵌套属性的复杂对象写入Azure表存储,这通常是使用Azure存储客户端SDK无法实现的。
2.0版本现在还支持读写IEnumerable
类型的属性,如列表、数组、字典到Azure表存储。
博客:https://doguarslan.wordpress.com/2016/02/03/writing-complex-objects-to-azure-table-storage/
用法:
//Flatten object and convert it to EntityProperty Dictionary
Dictionary<string, EntityProperty> flattenedProperties = ObjectFlattenerRecomposer.Flatten(complexObject);
// Create a DynamicTableEntity and set its PK and RK
DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey, rowKey);
dynamicTableEntity.Properties = flattenedProperties;
// Write the DynammicTableEntity to Azure Table Storage using client SDK
//Read the entity back from AzureTableStorage as DynamicTableEntity using the same PK and RK
DynamicTableEntity entity = [Read from Azure using the PK and RK];
//Convert the DynamicTableEntity back to original complex object.
Imagine original complexObject was of type Order.
Order order = ObjectFlattenerRecomposer.ConvertBack<Order>(entity.Properties);
首先,除了TableEntity和ITableEntity之外,还有另一种选择,那就是使用DataServiceKey属性来装饰你的类,如下面的例子所示:
[DataServiceKey("PartitionKey", "RowKey")]
public class MyEntity
{
public string PartitionKey {get; set;}
public string RowKey {get; set;}
public DateTime Timestamp {get; set;}
//other properties
}
然而,这并不能真正解决你不想将Azure实现泄漏到模型类中的问题。在这种情况下,我认为您可能希望使用LOKAD Fat Entities之类的包装器实现。Lokad将把模型对象的序列化/反序列化处理到包装器中,包装器又存储在表存储中。Lokad的一个缺点是,你的对象在存储中变得不透明,你不能用Azure存储资源管理器之类的东西浏览它们。