避免在 Azure 表存储中进行新的更新插入

发布于 2024-12-11 02:00:54 字数 872 浏览 7 评论 0原文

Steve Marx 在此处撰写了有关在 Azure 表存储中执行更新插入的新扩展方法的文章,作为新存储协议版本的一部分:

http://blog.smarx.com/posts/extension-methods-for-the-august-storage-features

但是,如果我想怎么办执行无条件合并或抛出的原始操作,而不是更新插入。我想合并一个对象,更新单个字段,但如果该实体不存在,则抛出异常,而不是创建一个仅包含我要合并的属性的新实体。

这可能吗?请注意,我想在其他地方使用 upsert,因此我开始让 IoC 为我提供从 GetDataServiceContext2011 而不是 GetDataServiceContext 创建的上下文。我想我可以在两者之间交替使用,但是当 Azure 团队更新官方库时,这将无济于事。

根据 MSDN

插入或合并实体操作使用 MERGE 动词,并且必须是 使用 2011-08-18 或更高版本调用。此外,它不 使用 If-Match 标头。这些属性区分此操作 来自更新实体操作,尽管请求正文相同 对于这两种操作。

那么,如何让存储库在保存时发出通配符 If-Match 而不是根本不发出 If-Match

Steve Marx writes about new extension methods to perform upserts in Azure Table Storage as part of the new storage protocol version here:

http://blog.smarx.com/posts/extension-methods-for-the-august-storage-features

However, what if I want to do the original operation of unconditional-merge-or-throw, rather than an upsert. I want to merge an object, updating a single field, but throw if the entity doesn't exist rather than create a new entity that contains only the properties I'm merging.

Is this possible? Note that I want to use upsert elsewhere, so I've taken to having IoC provide me with contexts created from GetDataServiceContext2011 instead of GetDataServiceContext. I suppose I could alternate between the two, but that won't help when the Azure team updates the official libraries.

According to MSDN:

The Insert Or Merge Entity operation uses the MERGE verb and must be
called using the 2011-08-18 version or newer. In addition, it does not
use the If-Match header. These attributes distinguish this operation
from the Update Entity operation, though the request body is the same
for both operations.

So, how do I get the storage library to emit a wildcard If-Match on save rather than emit no If-Match at all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

携君以终年 2024-12-18 02:00:54

只需使用带有星号的 AttachTo 来表示 etag。这将产生 If-Match: *。这是一个完整的工作示例:

class Entity : TableServiceEntity
{
    public string Text { get; set; }
    public Entity() { }
    public Entity(string rowkey) : base(string.Empty, rowkey) { }
}
class Program
{
    static void Update(CloudStorageAccount account)
    {
        var ctx = account.CreateCloudTableClient().GetDataServiceContext();

        var entity = new Entity("foo") { Text = "bar" };
        ctx.AttachTo("testtable", entity, "*");
        ctx.UpdateObject(entity);
        ctx.SaveChangesWithRetries();
    }

    static void Main(string[] args)
    {
        var account = CloudStorageAccount.Parse(args[0]);
        var tables = account.CreateCloudTableClient();
        tables.CreateTableIfNotExist("testtable");
        var ctx = tables.GetDataServiceContext();

        try { Update(account); } catch (Exception e) { Console.WriteLine("Exception (as expected): " + e.Message); }

        ctx.AddObject("testtable", new Entity("foo") { Text = "foo" });
        ctx.SaveChangesWithRetries();

        try { Update(account); } catch (Exception e) { Console.WriteLine("Unexpected exception: " + e.Message); }

        Console.WriteLine("Now text is: " + tables.GetDataServiceContext().CreateQuery<Entity>("testtable").Where(e => e.PartitionKey == string.Empty && e.RowKey == "foo").Single().Text);
        tables.DeleteTableIfExist("testtable");
    }
}

Just use AttachTo with an asterisk for an etag. That will result in an If-Match: *. Here's a complete working example:

class Entity : TableServiceEntity
{
    public string Text { get; set; }
    public Entity() { }
    public Entity(string rowkey) : base(string.Empty, rowkey) { }
}
class Program
{
    static void Update(CloudStorageAccount account)
    {
        var ctx = account.CreateCloudTableClient().GetDataServiceContext();

        var entity = new Entity("foo") { Text = "bar" };
        ctx.AttachTo("testtable", entity, "*");
        ctx.UpdateObject(entity);
        ctx.SaveChangesWithRetries();
    }

    static void Main(string[] args)
    {
        var account = CloudStorageAccount.Parse(args[0]);
        var tables = account.CreateCloudTableClient();
        tables.CreateTableIfNotExist("testtable");
        var ctx = tables.GetDataServiceContext();

        try { Update(account); } catch (Exception e) { Console.WriteLine("Exception (as expected): " + e.Message); }

        ctx.AddObject("testtable", new Entity("foo") { Text = "foo" });
        ctx.SaveChangesWithRetries();

        try { Update(account); } catch (Exception e) { Console.WriteLine("Unexpected exception: " + e.Message); }

        Console.WriteLine("Now text is: " + tables.GetDataServiceContext().CreateQuery<Entity>("testtable").Where(e => e.PartitionKey == string.Empty && e.RowKey == "foo").Single().Text);
        tables.DeleteTableIfExist("testtable");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文