We have a solution in which we parallelize reading and writing to Azure Table Storge.
Since TableServiceContext does not support reading an object in one thread and storing it in another thread, we want Entity to use a different Context. To do this, we need to install:
context.MergeOption = MergeOption.NoTracking;
And when updating (or deleting) the object we are calling:
context.AttachTo(entitySetName, entity, eTag);
However, for this we need to know ETag, and I do not know how to get it.
If the object was being tracked, we could use EntityDesciptor.ETag as follows:
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 do not track objects.
The only solution we found is this:
context.AttachTo(entitySetName, entity, "*");
... but that means we have concurrency problems in which the last record is always saved.
We also tried to build the following, which works on the 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"); }
A common problem with this approach, even if we could make it work, is that Microsoft makes no guarantees what the ETag looks like, so this may change over time.
So the question is: how do we get an ETag for an Azure table storage that is not being tracked?