避免Azure表存储中的新upsert

时间:2011-10-19 12:14:55

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

史蒂夫马克思撰写了关于在Azure表存储中执行upserts的新扩展方法,作为新存储协议版本的一部分:

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标头。这些属性区分了此操作   来自Update Entity操作,尽管请求主体是相同的   两种操作。

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

1 个答案:

答案 0 :(得分:5)

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