我试图控制Azure表实体的序列化,作为对How do I retrieve multiple types of entities using a single query to Azure Table Storage?的跟进,并遇到了(对我而言)意外行为。
检索项目时,无论我在保存实体时将其设置为什么,名称始终为“
<myaccountname>.Pets
”。为什么不保留typename?。
根据MSDN:
DataServiceContext.ResolveType
获取或设置一个函数,该函数用于覆盖客户端库从开放数据协议(OData)服务接收实体时使用的默认类型解析选项。
DataServiceContext.ResolveName
获取或设置一个函数,以便在将实体发送到数据服务时覆盖客户端库使用的默认类型解析策略。
并且this blog entry不应该是这种情况。
这是一个简单的测试:
public class Pet : TableServiceEntity { }
public class Cat : Pet { }
public class Dog : Pet { }
public class Test
{
public void RunTest()
{
//this.Create();
this.Read();
}
public TableServiceContext GetTableServiceContext()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
tableClient.CreateTableIfNotExist("Pets");
TableServiceContext serviceContext = tableClient.GetDataServiceContext();
serviceContext.ResolveName = (entityType) =>
{
return entityType.FullName;
};
serviceContext.ResolveType = (s) =>
{
return Type.GetType(s);
};
return serviceContext;
}
public void Create()
{
var serviceContext = this.GetTableServiceContext();
// Create entries
var cat = new Cat() { PartitionKey = "cats", RowKey = "1" };
serviceContext.AddObject("Pets", cat);
var dog = new Dog() { PartitionKey = "dogs", RowKey = "1" };
serviceContext.AddObject("Pets", dog);
serviceContext.SaveChangesWithRetries();
}
public void Read()
{
var serviceContext = this.GetTableServiceContext();
var pets = serviceContext.CreateQuery<Pet>("Pets").AsTableServiceQuery<Pet>().ToArray();
foreach (var pet in pets)
{
Console.WriteLine(pet.GetType());
}
}
}
答案 0 :(得分:1)
经过一番挖掘和讨论后,我发现azure表(无模式表)从未见过 typename 。相反,所有公共属性都是序列化的,只是将属性的有效负载发送到服务。
如果需要确定在有效负载中存储/检查属性所需的类型。这可以通过使用读/写实体事件来完成。
您的目标是立即返回异构集合,还是将其限制为仅一种类型。如果是后者,那么最好将类型存储在主键,行键中,如果可能,或者在单独的字段和查询中存储。