【问题标题】:TimeSpan property in Azure Table StorageAzure 表存储中的 TimeSpan 属性
【发布时间】:2012-07-06 15:41:36
【问题描述】:

我有一个具有TimeSpan 属性的实体,我想将其保存在 Azure 表存储中。当我尝试保存实体时出现错误:

无法转换为不受支持的类型“TimeSpan”

有没有办法进行自动转换或其他方式来支持TimeSpan

【问题讨论】:

    标签: .net azure azure-table-storage


    【解决方案1】:

    我将 TimeSpan 作为记号存储在 int 或 bigint 字段中并进行转换。您也可以将其存储为 varchar。我更喜欢刻度,因为如果需要,您可以在数据库中对其进行数学运算,并且它使范围比较更容易。如果您使用的是实体框架,则可以声明一个未映射的属性,该属性从您的数据库友好属性获取和设置 TimeSpan。

    看看Entities in Azure Tables。其中一部分描述了如何从 Azure 表存储中排除属性,这应该使我提出的 EF 建议也适用于 ATS。

    【讨论】:

    • 我正在使用 Azure 表存储(NoSQL 存储服务),所以我认为我不能使用 EF。我已经考虑过长期存储刻度 - 这就是我目前正在做的解决方法,但想看看是否有更好的方法。
    • 看看convective.wordpress.com/2009/12/30/entities-in-azure-tables。其中一部分描述了如何从 Azure 表存储中排除属性,这应该使我提出的 EF 建议也适用于 ATS。
    • 我们在这里使用记号。确保将存储的任何时间标准化为 UTC,以便应用刻度线可以获得正确的偏移量和时间。
    • @dunnry UTC 不适用于 TimeSpan,除非您将其用作存储时间的黑客,但这是一个好点。不过,DateTimeOffset 可能更适合这个目的。
    • @JamieSee - 我应该解释一下这个解释。我们使用刻度来根据偏移量计算日期时间(例如 someDateTime.AddTicks(-ticks))。在我们的例子中与时区无关。我们想知道 15 分钟前是从我们存储的某个日期时间开始的。当您不标准化您存储的 UTC 时间时,这会导致问题。当我赞成答案时,这更像是一个旁白。据我所知,大多数人最终都会使用时间跨度来计算日期时间......
    【解决方案2】:

    为了将 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); }
        }
    }
    

    【讨论】:

      【解决方案3】:

      Azure Storage SDK > v8.0.0 支持TimeSpan 类型甚至可以为空的TimeSpan? 类型。

      使用静态帮助方法TableEntity.Flatten 方法扁平化您的实体并写入表存储:

      https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.table.tableentity.flatten.aspx

      当您从表中读回实体时,使用TableEntity.Convertback 方法将其转换回您的原始实体。

      https://msdn.microsoft.com/en-us/library/azure/mt775432.aspx

      Flatten 和 Convertback 方法几乎支持任何类型的属性,除了 IEnumerable / ICollection 类型的索引属性。

      我编写了一个 TableEntityAdapter 类,它在下面调用 TableEntity.FlattenConvertBack 方法,便于开发人员使用。

      您需要做的就是将您的对象传递给这个适配器,仅此而已。 https://www.nuget.org/packages/TableEntityAdapter/

      如果您想进一步了解 Flatten 和 ConvertBack 方法如何在幕后工作,请查看我写的文章。 https://www.nuget.org/packages/ObjectFlattenerRecomposer/

      【讨论】:

        【解决方案4】:

        因为我在 Microsoft 客户端上遇到了限制,所以我编写了一个备用 Azure 表存储客户端 Lucifure Stash,其中包含许多高级抽象。

        Lucifure Stash,支持 > 64K 的数据列、列表、数组、枚举、序列化、变形、公共和私有属性和字段等。它免费供个人使用,可以从http://www.lucifure.com 或通过 NuGet.com (http://nuget.org/packages/LucifureStash) 下载。

        您可以轻松使用它将 TimeSpan 变形为 Azure 存储表支持的数据类型。

        【讨论】:

        • 谢谢@Lucifure,我会看看它是否符合我的需要。
        【解决方案5】:

        正如 JamieSee 建议的那样,您可以将 TimeSpan 作为刻度存储在某个 long int 中,您还可以将对象序列化为字节数组。

        无论您拥有什么复杂/不受支持的类,您始终可以将其序列化为字节数组并上传,然后对其进行检索、反序列化并将其转换回任何类型。当我需要上传 KeyValuePairs 列表时,我这样做了。

        您可以在属性 getter 和 setter 中创建自动转换。

        【讨论】:

          猜你喜欢
          • 2019-04-04
          • 2012-08-06
          • 2011-09-28
          • 1970-01-01
          • 1970-01-01
          • 2011-01-17
          • 1970-01-01
          • 2016-05-31
          • 2014-10-18
          相关资源
          最近更新 更多