Upsert


public class TableServiceContextV2 : TableServiceContext
{
    private const string StorageVersionHeader = "x-ms-version";
    private const string August2011Version = "2011-08-18";

    public TableServiceContextV2(string baseAddress, StorageCredentials credentials):
        base (baseAddress, credentials)
    {
        this.SendingRequest += SendingRequestWithNewVersion;
    }

    private void SendingRequestWithNewVersion(object sender, SendingRequestEventArgs e)
    {
        HttpWebRequest request = e.Request as HttpWebRequest;

        // Apply the new storage version as a header value
        request.Headers[StorageVersionHeader] = August2011Version;
    }
}

InsertOrMerge Entity 

// The mobile app collects the customer's phone number
CustomerEntity mobileCustomer = new CustomerEntity("John", "Smith");
mobileCustomer.PhoneNumber = "505-555-0122";

// Notice how the AttachTo method is called with a null Etag which indicates that this is an Upsert Command
mobileServiceContext.AttachTo(customersTableName, mobileCustomer, null);

mobileServiceContext.UpdateObject(mobileCustomer);

// No SaveChangeOptions is used, which indicates that a MERGE verb will be used. This set of steps will result in an InsertOrMerge command to be sent to Windows Azure Table
mobileServiceContext.SaveChanges();

Note:  Prior to version “20011-08-18”, Windows Azure Table will reject any MERGE or PUT requests made against it where the If-Match header was not specified, as those earlier versions do not support Upsert commands.

you will receive error like
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\r\n<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\r\n  <code>InvalidInput</code>\r\n  <message xml:lang=\"en-US\">0:One of the request inputs is not valid.\nRequestId:eba57c2c-2be4-416c-8098-5b662e039bad\nTime:2012-01-10T16:18:35.1336142Z</message>\r\n</error>"

Here is the verification:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using System.Data.Services.Client;
using System.Net;

namespace AzureStorageTest
{
    public class TableServiceContextV2 : TableServiceContext
    {
        private const string StorageVersionHeader = "x-ms-version";
//        private const string August2011Version = "2011-08-18";
        private const string August2011Version = "2009-09-19";

        public TableServiceContextV2(string baseAddress, StorageCredentials credentials) :
            base(baseAddress, credentials)
        {
            this.SendingRequest += SendingRequestWithNewVersion;
        }

        private void SendingRequestWithNewVersion(object sender, SendingRequestEventArgs e)
        {
            HttpWebRequest request = e.Request as HttpWebRequest;

            // Apply the new storage version as a header value
            request.Headers[StorageVersionHeader] = August2011Version;
        }
    }
}

using System;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Data.Services.Common;
using System.Data.Services.Client;

namespace AzureStorageTest
{
    class Program
    {
        static void Main(string[] args)
        {

            CloudStorageAccount account = CloudStorageAccount.
            Parse(System.Configuration.ConfigurationManager.AppSettings["StorageAccountConnectionString"]);

            CloudTableClient tableClient = account.CreateCloudTableClient();

            //Create Movie Table 
            string tableName = "Movies";
            tableClient.CreateTableIfNotExist(tableName);
            //TableServiceContext context = tableClient.GetDataServiceContext();
            TableServiceContext context = new TableServiceContextV2(
                "https://cloudcover.table.core.windows.net", account.Credentials);

            //context.AddObject(tableName, new Movie("Action", "White Water Rapids Survival"));
            //context.AddObject(tableName, new Movie("Action", "You are the one"));
            context.SaveChangesWithRetries();
            //Update
            context.MergeOption = MergeOption.NoTracking;
            var q = (from movie in context.CreateQuery<Movie>(tableName)
                     where movie.PartitionKey == "Action" && movie.Rating > 4.0
                     select movie).AsTableServiceQuery<Movie>();

            foreach (Movie movieToUpdate in q)
            {
                movieToUpdate.Favorite = true;
                string time = movieToUpdate.Timestamp.ToString();
                context.AttachTo(tableName, movieToUpdate, null);
                context.UpdateObject(movieToUpdate);
            }

            //WHEN HERE HAPPEN CONCURRENCY UPDATE ! ! !

            context.SaveChangesWithRetries(SaveChangesOptions.Batch);
            Console.ReadKey();

        }
    }

    [DataServiceKey("PartitionKey", "RowKey")]
    public class Movie
    {
        /// Movie Category is the partition key 
        public string PartitionKey { get; set; }
        /// Movie Title is the row key 
        public string RowKey { get; set; }
        public DateTime Timestamp { get; set; }
        public int ReleaseYear { get; set; }
        public double Rating { get; set; }
        public string Language { get; set; }
        public bool Favorite { get; set; }

        public Movie() { }
        public Movie(string partitionKey, string rowkey)
        {
            PartitionKey = partitionKey;
            RowKey = rowkey;
            Rating = 5;
        }
    }

}

InsertOrReplace Entity

Since we wish to send an InsertOrReplace Entity request, we would first need to AttachTo the websiteServiceContext without providing any Etag value before calling the UpdateObject method. In addition, the SaveChanges method would need to be invoked with the SaveChangesOptions.ReplaceOnUpdate parameter to indicate that the Upsert operation should replace the existing entity in case it exists.

CustomerEntity mailServiceCustomer = new CustomerEntity("David", "Alexander");
mailServiceCustomer.PhoneNumber = "333-555-0155";
mailServiceCustomer.Address = "234 Main St, Anaheim, TX, 65000";
mailServiceCustomer.Email = "David@wideworldimporters.com";

// Note how SaveChanges is called with ReplaceOnUpdate which is the differentiation
// factor between an InsertOrMerge Entity API and InsertOrReplace Entity Api
websiteServiceContext.AttachTo(customersTableName, mailServiceCustomer);
websiteServiceContext.UpdateObject(mailServiceCustomer);
websiteServiceContext.SaveChanges(SaveChangesOptions.ReplaceOnUpdate);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值