4
votes

We have a solution where we parallelize reading and writing to Azure Table Storge.

Because the TableServiceContext does not support reading an entity on one thread and saving it on another thread, we want to keep the Entity using another Context. To do that we need to set:

context.MergeOption = MergeOption.NoTracking;

And when updating (or removing) an entity we call:

context.AttachTo(entitySetName, entity, eTag);

However to do that we need to know the ETag, and I don't know how to get that.

If the entity was tracked, we could use the EntityDesciptor.ETag like this:

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

... but context.Entities are empty because we don't track entities.

The only solution we found so fare is:

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

... but that means we have concurrency problems where the last to write always wins.

We also tried to construct the following which works on local Compute Emulator but not in the cloud:

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");
}

The general problem with this approach even if we could get it to work, is that Microsoft does not make any garanties about how the ETag looks, so this could change over time.

So the question is: How do we get ETag of a Azure Table storage Entity that is not tracked?

2

2 Answers

2
votes

I think you'll have to note the etag when you read the entity. (There's probably an event you can hook, maybe ReadingEntity where you can access the etag and store it somewhere.)

0
votes

I have written an alternate table storage client which is very explicit in exposing the etag and can be used context free and is thread safe. It may work for you. It is available at www.lucifure.com.