/// <summary> /// Combines multiple requests into a batch to make these requests atomic, i.e. all req rollback if one fails /// Refer: https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/execute-batch-operations-using-web-api /// </summary> /// <returns> /// Task /// </returns> public async Task BatchUpdate(string rowGuid, string baseId, dynamic newData, string tableName) { var batchId = $"batch_batchid"; var changesetId = $"changeset_changesetid"; var dataverseRequests = new DataverseBatchRequest[2]; // Custom Update // 1. Mark old var updateTable = new DataverseTable(); updateTable.Islatest = Constant.IsLatestFalse; var updateTableJson = JsonConvert.SerializeObject(updateTable); dataverseRequests[0] = new DataverseBatchRequest("PATCH", $"https://{dataverseConfig.Value.ApiBaseUrl}/{tableName}({rowGuid})", updateTableJson); // 2. Insert row newData.Baseid = baseId; newData.Islatest = Constant.IsLatestTrue; // Mark latest row as "1" var newDataJson = JsonConvert.SerializeObject(newData); dataverseRequests[1] = new DataverseBatchRequest("POST", $"https://{dataverseConfig.Value.ApiBaseUrl}/{tableName}", newDataJson); // Build MultipartRequest content var reqContent = MultipartHelper.GenerateAtomicRequestContent(batchId, changesetId, dataverseRequests); dataverseClient.DefaultRequestHeaders.Accept.Clear(); UriBuilder requestUri = new UriBuilder("https", dataverseConfig.Value.ApiBaseUrl); requestUri.Path = "$batch"; // Execute Batch request var response = await dataverseClient.PostAsync(requestUri.Uri, reqContent); if (!response.IsSuccessStatusCode) { throw new DataverseException(Constant.InvalidUpdateDataColumns); } }
/// <summary> /// Combines multiple requests into a batch to make these requests atomic, i.e. all req rollback if one fails /// Refer: https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/execute-batch-operations-using-web-api /// /// 1a. Mark existing record as old. Passing the record's GUID to be marked as old /// 1b. Insert updated record as new /// 2. Insert new record /// 3. Set baseId = inserted row's guid /// </summary> /// <returns> /// Task /// </returns> public async Task BatchUpdateAdd( string rowGuid, string baseId, dynamic updatedData, string updateTableName, dynamic newData, string newDataIdColumn, string addTableName) { var batchId = $"batch_batchid"; var changesetId = $"changeset_changesetid"; var dataverseRequests = new DataverseBatchRequest[3]; // 1a. Mark old (Custom Update) var updateTable = new DataverseTable(); updateTable.Islatest = Constant.IsLatestFalse; string jsonTestTable = JsonConvert.SerializeObject(updateTable); dataverseRequests[0] = new DataverseBatchRequest("PATCH", $"https://{dataverseConfig.Value.ApiBaseUrl}/{updateTableName}({rowGuid})", jsonTestTable); // 1b. Insert updated row updatedData.Baseid = baseId; updatedData.Islatest = Constant.IsLatestTrue; // Mark latest row as "1" var updatedDataJson = JsonConvert.SerializeObject(updatedData); dataverseRequests[1] = new DataverseBatchRequest("POST", $"https://{dataverseConfig.Value.ApiBaseUrl}/{updateTableName}", updatedDataJson); // 2. Insert new row newData.Islatest = Constant.IsLatestTrue; // Mark latest row as "1" var newDataJson = JsonConvert.SerializeObject(newData); // NOTE: Set preferResponse = true for atmost one API request in a batch var preferDataResponse = true; dataverseRequests[2] = new DataverseBatchRequest("POST", $"https://{dataverseConfig.Value.ApiBaseUrl}/{addTableName}", newDataJson, preferDataResponse); // Build MultipartRequest content var reqContent = MultipartHelper.GenerateAtomicRequestContent(batchId, changesetId, dataverseRequests); dataverseClient.DefaultRequestHeaders.Accept.Clear(); UriBuilder requestUri = new UriBuilder("https", dataverseConfig.Value.ApiBaseUrl); requestUri.Path = "$batch"; // Execute Batch request var response = await dataverseClient.PostAsync(requestUri.Uri, reqContent); if (!response.IsSuccessStatusCode) { throw new DataverseException(Constant.InvalidUpdateDataColumns); } // Return when data response was not requested if (!preferDataResponse) { return; } // 3. Set baseId = inserted row's guid var resString = await response.Content.ReadAsStringAsync(); // Get JSON data from the batch response var insertedRowJson = MultipartHelper.GetJsonData(resString); var insertedRow = JObject.Parse(insertedRowJson); var insertedRowGuid = Convert.ToString(insertedRow[newDataIdColumn], cultureInfo); // Create JSON for update operation i.e. set baseId = rowGuid of inserted row var table = new DataverseTable(); table.Baseid = insertedRowGuid; var jsonTable = JsonConvert.SerializeObject(table); var content = new StringContent(jsonTable, Encoding.UTF8, "application/json"); // Update operation requestUri = new UriBuilder("https", dataverseConfig.Value.ApiBaseUrl); requestUri.Path = $"{addTableName}({insertedRowGuid})"; response = await dataverseClient.PatchAsync(requestUri.Uri, content); if (!response.IsSuccessStatusCode) { throw new DataverseException(Constant.InvalidUpdateDataColumns); } }