【发布时间】:2012-07-06 15:41:36
【问题描述】:
我有一个具有TimeSpan 属性的实体,我想将其保存在 Azure 表存储中。当我尝试保存实体时出现错误:
无法转换为不受支持的类型“TimeSpan”
有没有办法进行自动转换或其他方式来支持TimeSpan?
【问题讨论】:
标签: .net azure azure-table-storage
我有一个具有TimeSpan 属性的实体,我想将其保存在 Azure 表存储中。当我尝试保存实体时出现错误:
无法转换为不受支持的类型“TimeSpan”
有没有办法进行自动转换或其他方式来支持TimeSpan?
【问题讨论】:
标签: .net azure azure-table-storage
我将 TimeSpan 作为记号存储在 int 或 bigint 字段中并进行转换。您也可以将其存储为 varchar。我更喜欢刻度,因为如果需要,您可以在数据库中对其进行数学运算,并且它使范围比较更容易。如果您使用的是实体框架,则可以声明一个未映射的属性,该属性从您的数据库友好属性获取和设置 TimeSpan。
看看Entities in Azure Tables。其中一部分描述了如何从 Azure 表存储中排除属性,这应该使我提出的 EF 建议也适用于 ATS。
【讨论】:
为了将 TimeSpan 存储到 CloudTable 中,我使用了 long 属性,它使用 TimeSpan 属性进行翻译:
public class MyEntity : Microsoft.WindowsAzure.Storage.Table.TableEntity
{
public TimeSpan MyDuration { get; set; }
// Workaround the fact that TableEntity does not automatically store a `TimeSpan`
public long MyDurationTicks
{
get { return MyDuration.Ticks; }
set { MyDuration = TimeSpan.FromTicks(value); }
}
}
【讨论】:
Azure Storage SDK > v8.0.0 支持TimeSpan 类型甚至可以为空的TimeSpan? 类型。
使用静态帮助方法TableEntity.Flatten 方法扁平化您的实体并写入表存储:
当您从表中读回实体时,使用TableEntity.Convertback 方法将其转换回您的原始实体。
https://msdn.microsoft.com/en-us/library/azure/mt775432.aspx
Flatten 和 Convertback 方法几乎支持任何类型的属性,除了 IEnumerable / ICollection 类型的索引属性。
我编写了一个 TableEntityAdapter 类,它在下面调用 TableEntity.Flatten 和 ConvertBack 方法,便于开发人员使用。
您需要做的就是将您的对象传递给这个适配器,仅此而已。 https://www.nuget.org/packages/TableEntityAdapter/
如果您想进一步了解 Flatten 和 ConvertBack 方法如何在幕后工作,请查看我写的文章。 https://www.nuget.org/packages/ObjectFlattenerRecomposer/
【讨论】:
因为我在 Microsoft 客户端上遇到了限制,所以我编写了一个备用 Azure 表存储客户端 Lucifure Stash,其中包含许多高级抽象。
Lucifure Stash,支持 > 64K 的数据列、列表、数组、枚举、序列化、变形、公共和私有属性和字段等。它免费供个人使用,可以从http://www.lucifure.com 或通过 NuGet.com (http://nuget.org/packages/LucifureStash) 下载。
您可以轻松使用它将 TimeSpan 变形为 Azure 存储表支持的数据类型。
【讨论】:
正如 JamieSee 建议的那样,您可以将 TimeSpan 作为刻度存储在某个 long int 中,您还可以将对象序列化为字节数组。
无论您拥有什么复杂/不受支持的类,您始终可以将其序列化为字节数组并上传,然后对其进行检索、反序列化并将其转换回任何类型。当我需要上传 KeyValuePairs 列表时,我这样做了。
您可以在属性 getter 和 setter 中创建自动转换。
【讨论】: