我们如何获得未跟踪的Azure表存储实体的ETag?

时间:2011-10-22 11:53:37

标签: azure azure-table-storage

我们有一个解决方案,我们可以并行读取和写入Azure Table Storge。

因为TableServiceContext不支持在一个线程上读取实体并将其保存在另一个线程上,所以我们希望使用另一个Context来保持实体。为此,我们需要设置:

context.MergeOption = MergeOption.NoTracking;

当更新(或删除)我们称之为的实体时:

context.AttachTo(entitySetName, entity, eTag);

然而,要做到这一点,我们需要知道ETag,我不知道如何得到它。

如果跟踪了实体,我们可以像这样使用EntityDesciptor.ETag:

private string GetETagFromEntity<T>(T entity) where T : TableServiceEntity
{
    return context.Entities.Single(entityDescriptor =>
                                   entityDescriptor.Entity == entity).ETag;
}

...但是context.Entities是空的,因为我们不跟踪实体。

我们发现的唯一解决方案是:

context.AttachTo(entitySetName, entity, "*");

...但这意味着我们遇到了并发问题,最后写的总是胜出。

我们还尝试构建以下适用于本地Compute Emulator但不适用于云的内容:

private string GetETagFromEntity<T>(T entity) where T : TableServiceEntity
{
    string datePart = entity.Timestamp.ToString("yyyy-MM-dd");
    string hourPart = entity.Timestamp.ToString("HH");
    string minutePart = entity.Timestamp.ToString("mm");
    string secondPart = entity.Timestamp.ToString("ss");
    string milisecondPart = entity.Timestamp.ToString("fff").TrimEnd('0');

    return string.Format(
              "W/\"datetime'{0}T{1}%3A{2}%3A{3}.{4}Z'\"",
               datePart,
               hourPart,
               minutePart,
               secondPart,
               milisecondPart
           ).Replace(".Z", "Z");
}

这种方法的一般问题,即使我们可以让它发挥作用,是微软不会对ETag的外观做出任何保证,所以这可能会随着时间而改变。

所以问题是:我们如何获得未跟踪的Azure表存储实体的ETag?

2 个答案:

答案 0 :(得分:2)

我认为你在阅读实体时必须注意etag。 (可能有一个你可以挂钩的事件,也许是ReadingEntity,你可以在那里访问etag并将其存储在某个地方。)

答案 1 :(得分:0)

我编写了一个备用表存储客户端,它在公开etag时非常明确,可以使用上下文,并且是线程安全的。 可能为您工作。可在www.lucifure.com上找到。