2011-10-19 70 views
2

史蒂夫马克思新UPSERT写了关于新的扩展方法在Azure Table中存储这里的新存储协议版本的一部分来执行upserts:避免在Azure Table中存储

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

回答

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"); 
    } 
} 
+0

谢谢。我对这件事感到很沮丧。 :-P –

+0

@smarx etag实际上做了什么?我试图谷歌,但没有找到任何解释。 – starcorn

+0

@starcom在这种情况下,问题本身给出了答案并提供了源代码(MSDN)。 – smarx