[Azure] C# + Microsoft.Azure.Cosmos.Table v1+ Azure Storage Table -InsertOrReplace vs InsertOrMerge

2021-01-06

這問題一直困擾我很久,我就想說測一下到底是啥意思 在 TableOperation 中有一個 InsertOrReplace 還有 InsertOrMerge 到底有啥不同,不如就乾脆寫一個程式測試一下它們的行為,這也對之後在設計系統上會有幫助..






前置作業 首先你要 安裝 nuget https://www.nuget.org/packages/Microsoft.Azure.Cosmos.Table ,這邊我撰寫案例是用 .net core 3.1;在 Azure Portal  開一個 儲存體帳戶,並且在左側的存取金鑰中拿到 Connection String.



解釋案例,我會先寫入一筆資料,並且 是使用 InsertOrReplace ,我再取出來,之後再用在寫一次,這時候我有改變某些 Properties 在使用 InsertOrMerge 寫回,取出後看看答案

var tableClient = CloudStorageAccount.Parse(_ConnectionString).CreateCloudTableClient(new TableClientConfiguration()); var table = tableClient.GetTableReference("table1"); //InsertOrReplace var sampleObject = new User("CLASSA", "DATAKEY1") { Name = "DONMA1-INSERTUPDATE", Age = 1, Meta = "META-INSERTUPDATE", Create = new DateTime(2001, 1, 1).AddDays(1), LastLoginDate = DateTime.Now }; table.Execute(TableOperation.InsertOrReplace(sampleObject)); //Read Data After InsertOrReplace Console.WriteLine("------ Read Data After InsertOrReplace ------"); var data1 = table.Execute(TableOperation.Retrieve<User>("CLASSA", "DATAKEY1")).Result; Console.WriteLine(JsonConvert.SerializeObject(data1)); Console.WriteLine("\r\n\r\n\r\n"); //InsertOrMerge var sampleObject2 = new User("CLASSA", "DATAKEY1") { Name = "DONMA1-INSERTORMERGE", Age = null, //刻意放 null 測試 Meta = null, //刻意放 null 測試 Create = new DateTime(2020, 1, 1).AddDays(1), LastLoginDate = null //刻意放 null 測試 }; table.Execute(TableOperation.InsertOrMerge(sampleObject2)); //Read Data After InsertOrMerge Console.WriteLine("------ Read Data After InsertOrMerge ------"); var data2 = table.Execute(TableOperation.Retrieve<User>("CLASSA", "DATAKEY1")).Result; Console.WriteLine(JsonConvert.SerializeObject(data2)); //Result: // ------ Read Data After InsertOrReplace ------ //{"Name":"DONMA1-INSERTUPDATE","Age":1,"Create":"2001-01-01T16:00:00Z","Friends":[],"Meta":"META-INSERTUPDATE","LastLoginDate":"2021-01-06T01:58:46.1801935Z","PartitionKey":"CLASSA","RowKey":"DATAKEY1","Timestamp":"2021-01-06T09:58:07.4542422+08:00","ETag":"W/\"datetime'2021-01-06T01%3A58%3A07.4542422Z'\""} //------ Read Data After InsertOrMerge ------ //{"Name":"DONMA1-INSERTORMERGE","Age":1,"Create":"2020-01-01T16:00:00Z","Friends":[],"Meta":"META-INSERTUPDATE","LastLoginDate":"2021-01-06T01:58:46.1801935Z","PartitionKey":"CLASSA","RowKey":"DATAKEY1","Timestamp":"2021-01-06T09:58:07.7934816+08:00","ETag":"W/\"datetime'2021-01-06T01%3A58%3A07.7934816Z'\""} public class User : Microsoft.Azure.Cosmos.Table.TableEntity { public string Name { get; set; } public int? Age { get; set; } public DateTime Create { get; set; } public List<User> Friends { get; set; } public string Meta { get; set; } public DateTime? LastLoginDate { get; set; } public User() { Friends = new List<User>(); } public User(string classId, string userId) { PartitionKey = classId; RowKey = userId; Friends = new List<User>(); } }

Result:

------ Read Data After InsertOrReplace ------
{"Name":"DONMA1-INSERTUPDATE ","Age":1,"Create":"2001-01-01T16:00:00Z","Friends":[],"Meta":"META-INSERTUPDATE","LastLoginDate":"2021-01-06T01:58:46.1801935Z","PartitionKey":"CLASSA","RowKey":"DATAKEY1","Timestamp":" 2021-01-06T09:58:07.4542422+08:00","ETag":"W/\"datetime'2021-01-06T01%3A58%3A07.4542422Z'\""}



------ Read Data After InsertOrMerge ------
{"Name":" DONMA1-INSERTORMERGE","Age":1,"Create":"2020-01-01T16:00:00Z","Friends":[],"Meta":"META-INSERTUPDATE","LastLoginDate":"2021-01-06T01:58:46.1801935Z","PartitionKey":"CLASSA","RowKey":"DATAKEY1","Timestamp":" 2021-01-06T09:58:07.7934816+08:00","ETag":"W/\"datetime'2021-01-06T01%3A58%3A07.7934816Z'\""}

所以結論,如果原本存在的資料,之後如果使用 InsertOrMerge ,你放空( null ) 的值,就會保留資料庫上面的,如果新的資料友值( 非 null ) 就會用新的資料代替..

reference :

https://docs.microsoft.com/zh-tw/rest/api/storageservices/insert-or-merge-entity

https://stackoverflow.com/questions/45490528/insertorupdate-vs-insertormerge-in-azure-storage-tables-what-is-the-difference


當麻許的碎念筆記 2014 | Donma Hsu Design.