我想使用这样的实体进行表存储:
public class MyEntity
{
public String Text { get; private set; }
public Int32 SomeValue { get; private set; }
public MyEntity(String text, Int32 someValue)
{
Text = text;
SomeValue = someValue;
}
}
但是这是不可能的,因为ATS需要
前两件事是我不想做的两件事。为什么我希望任何人都可以更改一些应该只读的数据?或者以不一致的方式创建此类对象(那么 .ctor 的用途是什么?),或者更糟糕的是,更改 PartitionKey 或 RowKey。为什么我们仍然受到这些反序列化要求的限制?
我不喜欢以这种方式开发软件,我怎样才能以可以自己序列化和反序列化对象的方式使用表存储库?我认为只要对象继承自 TableServiceEntity 就应该不是问题。
到目前为止,我必须保存一个对象,但我不知道如何检索它:
Message m = new Message("message XXXXXXXXXXXXX");
CloudTableClient tableClient = account.CreateCloudTableClient();
tableClient.CreateTableIfNotExist("Messages");
TableServiceContext tcontext = new TableServiceContext(account.TableEndpoint.AbsoluteUri, account.Credentials);
var list = tableClient.ListTables().ToArray();
tcontext.AddObject("Messages", m);
tcontext.SaveChanges();
有什么方法可以避免这些反序列化要求或获取原始对象吗?
干杯。
如果您想使用存储客户端库,那么是的,您可以或不可以对要存储的对象执行哪些操作。第 1 点是正确的。我将第 2 点扩展为“您想要存储的所有属性都必须是公共且读/写的”(对于整数属性,您可以使用只读属性,并且不会尝试保存它们),但您不这样做实际上不必继承自
TableServiceEntity
。
TableServiceEntity
只是一个非常轻量级的类,具有 PartitionKey、RowKey、Timestamp 属性,并用 DataServiceKey
属性装饰(用 Reflector 看一下)。您可以对自己创建的类执行所有这些操作,并且该类不是从 TableServiceEntity 继承的(请注意,这些属性的大小写很重要)。
如果这仍然无法让您对如何构建类有足够的控制,您可以随时忽略存储客户端库,直接使用 REST API。这将使您能够以您喜欢的任何方式序列化和反序列化 XML。您将失去使用该库带来的所有好处,例如在 LINQ 中创建查询的能力。
表存储的 ADO.NET 包装器周围的限制确实有些痛苦。您还可以采用在 Lokad.Cloud 中实现的 Fat Entity 方法。这将为您的实体序列化提供更大的灵活性。
只是不要使用继承。
如果您想使用自己的 POCO,请根据需要创建您的类,并创建一个单独的 tableEntity 包装器/容器类,该类保存 pK 和 rK 并将您的类作为序列化字节数组承载。
你可以使用组合来实现你想要的。 根据存储需要创建表实体,并创建 POCO 作为那些提供您希望应用程序代码的其余部分看到的 API 的包装器。 您甚至可以混合一些接口以获得更好的代码。
如何使用 System.Reflection.Emit 在运行时生成 POCO 包装器 http://blog.kloud.com.au/2012/09/30/a-better-dynamic-tableserviceentity/