我们如何获取未跟踪的Azure表存储实体的ETag?
我们有一个解决方案,可以并行读取和写入 Azure 表存储。
由于 TableServiceContext 不支持在一个线程上读取实体并将其保存在另一个线程上,因此我们希望使用另一个 Context 来保留该实体。为此,我们需要设置:
context.MergeOption = MergeOption.NoTracking;
当更新(或删除)实体时,我们调用:
context.AttachTo(entitySetName, entity, eTag);
然而,要做到这一点,我们需要知道 ETag,但我不知道如何获取它。
如果实体被跟踪,我们可以像这样使用 EntityDeciptor.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, "*");
...但这意味着我们存在并发问题,最后写入的总是获胜。
我们还尝试构建以下内容,该内容适用于本地计算模拟器,但不适用于云:
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");
}
即使我们可以让它工作,这种方法的一般问题是 Microsoft 不对 ETag 的外观做出任何保证,因此这可能会随着时间的推移而改变。
那么问题是:我们如何获取未跟踪的Azure表存储实体的ETag?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您在阅读实体时必须记下 etag。 (可能有一个您可以挂钩的事件,也许是 ReadingEntity,您可以在其中访问 etag 并将其存储在某个地方。)
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.)
我编写了一个备用表存储客户端,它在公开 etag 方面非常明确,并且可以与上下文无关并且是线程安全的。它可能适合您。可在 www.lucisure.com 上获取。
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.