【问题标题】:Avoiding the new upsert in Azure Table Storage避免 Azure 表存储中的新 upsert
【发布时间】:2011-10-19 12:14:55
【问题描述】:

Steve Marx 写了关于在 Azure 表存储中执行 upsert 的新扩展方法,作为新存储协议版本的一部分:

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

但是,如果我想做无条件合并或抛出的原始操作,而不是 upsert。我想合并一个对象,更新单个字段,但如果实体不存在则抛出,而不是创建一个仅包含我正在合并的属性的新实体。

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

根据MSDN

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

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

【问题讨论】:

    标签: c# azure upsert azure-table-storage azure-storage


    【解决方案1】:

    只需使用带有星号的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");
        }
    }
    

    【讨论】:

    • 谢谢。我对此感到有点愚蠢。 :-P
    • @smarx etag 实际上是做什么的?我试图用谷歌搜索它,但没有找到任何解释。
    • @starcom 在这种情况下,问题本身给出了答案并提供了来源(MSDN)。
    猜你喜欢
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 1970-01-01
    • 2019-12-06
    • 2018-04-12
    • 1970-01-01
    • 2018-01-30
    相关资源
    最近更新 更多