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?