Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现Azure表&x27;支持嵌套对象和自定义特性类型的ITableEntity接口_C#_.net_Azure_Azure Table Storage - Fatal编程技术网

C# 实现Azure表&x27;支持嵌套对象和自定义特性类型的ITableEntity接口

C# 实现Azure表&x27;支持嵌套对象和自定义特性类型的ITableEntity接口,c#,.net,azure,azure-table-storage,C#,.net,Azure,Azure Table Storage,Azure表存储仅支持基本数据类型,如(int、string、Guid、DateTime)等。这使得存储本身包含对象(即嵌套对象)的对象变得困难。也不支持直接存储列表和其他此类集合数据类型 为此,我创建了一个CustomEntity类,该类继承自ITableEntity,并使用新引入的TableEntity.flatte(…)和TableEntity.ConvertBack(…)方法实现了ReadEntity和WriteEntity方法。我现在只专注于存储嵌套对象 public class Cu

Azure表存储仅支持基本数据类型,如(int、string、Guid、DateTime)等。这使得存储本身包含对象(即嵌套对象)的对象变得困难。也不支持直接存储列表和其他此类集合数据类型

为此,我创建了一个CustomEntity类,该类继承自ITableEntity,并使用新引入的
TableEntity.flatte(…)
TableEntity.ConvertBack(…)
方法实现了ReadEntity和WriteEntity方法。我现在只专注于存储嵌套对象

public class CustomEntity : ITableEntity
{
    // Partition Key, Row Key, Timestamp and ETag here

    public void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
    {
        CustomEntity customEntity = TableEntity.ConvertBack<CustomEntity>(properties, operationContext);
        // Do the memberwise clone for this object from the returned CustomEntity object
        CloneThisObject(this, customEntity);
    }

    public IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
    {
        IDictionary<string, EntityProperty> flattenedProperties = TableEntity.Flatten(this, operationContext);
        flattenedProperties.Remove("PartitionKey");
        flattenedProperties.Remove("RowKey");
        flattenedProperties.Remove("Timestamp");
        flattenedProperties.Remove("ETag");
        return flattenedProperties;
    }
}
公共类CustomEntity:ITableEntity
{
//这里有分区键、行键、时间戳和ETag
public void ReadEntity(IDictionary属性,OperationContext OperationContext)
{
CustomEntity CustomEntity=TableEntity.ConvertBack(属性、操作上下文);
//从返回的CustomEntity对象执行此对象的memberwise克隆
CloneThisObject(此,customEntity);
}
公共IDictionary WriteEntity(OperationContext OperationContext)
{
IDictionary FlattedProperties=TableEntity.Flatte(这是operationContext);
FlattedProperties.Remove(“PartitionKey”);
展平属性。删除(“行键”);
FlattedProperties.Remove(“时间戳”);
平坦属性。移除(“ETag”);
返回平坦的属性;
}
}
我在我的模型中使用了上述代码,并且能够成功地在Azure表中插入嵌套对象。当我想要检索同一个对象时,问题就出现了。代码在
table.Execute(TableOperation.Retrieve(partitionKey,rowKey))
命令处陷入无限循环

此外,虽然在CustomEntity对象的插入操作中命中了WriteEntity代码,但在检索实体时未命中ReadEntity代码。我错过了什么?任何帮助都将不胜感激

检索实体时未命中ReadEntity代码

Execute(TableOperation.Retrieve(partitionKey,rowKey))方法将返回DynamicTableEntity。它不会调用您定义的ReadEntity方法。如果执行如下查询,将命中ReadEntity方法

var  entity = table.Execute(TableOperation.Retrieve<CustomEntity>(partitionKey, rowKey)).Result;
从表中获取员工实体

CloudTable table = tableClient.GetTableReference("tableName");
var entities = CustomEntity.GetEntities<EmployeeEntity>(table, "PartitionKey eq 'pk'"); 
CloudTable table=tableClient.GetTableReference(“tableName”);
var entities=CustomEntity.GetEntities(表“PartitionKey eq'pk'”);

可能有点晚了,但希望更新答案,因为这样可以解决您的问题。我更新了Object Flatter重新编译api,以支持
IEnumerable/ICollection
类型属性。基本上,您可以使用Object Flatter Recomposer api的v2.0将几乎所有内容写入表存储:


api透明地处理所有转换/序列化和反序列化,因此无需编写您自己的逻辑。

您能否发布一篇简短、完整的问题重述?为什么您要尝试在一个设计为键值存储的引擎中创建一种文档存储?为什么不使用CosmosDB呢?或者只是将json文档存储在表存储列中?@PeterBons想要使用表存储和分层对象有很多原因。。价格、性能、查询模式、批处理等更新?你试过我的建议了吗?如果您还有其他问题,请随时告诉我。谢谢您的帮助。我尝试了您关于使用Retrieve的建议,并成功地从Azure表中写入和读取了一个实体。然而,考虑到即使使用展平和ConvertBack方法,我也不能使用集合对象,我最终编写了自己的序列化、反序列化逻辑;dynamicTableEntity.Properties=TableEntity.flatte(new T(),new OperationContext())同样,ConvertBack应该已经处理了PK、RK、ETag和Timestamp,因为我记得不需要显式赋值。
public class EmployeeEntity : CustomEntity
{
    public EmployeeEntity(string lastName, string firstName)
    {
        this.PartitionKey = lastName;
        this.RowKey = firstName;
    }

    public EmployeeEntity() { }

    public string Email { get; set; }

    public Address ContactAddress { get; set; }
}

public class Address
{
    public string Province { get; set; }

    public string City { get; set; }
}
CloudTable table = tableClient.GetTableReference("tableName");
var entities = CustomEntity.GetEntities<EmployeeEntity>(table, "PartitionKey eq 'pk'");