static async Task SaveBatches(Stack <LCBatch> batches) { while (batches.Count > 0) { LCBatch batch = batches.Pop(); // 特殊处理 File 依赖 IEnumerable <LCFile> dirtyFiles = batch.objects.Where(item => (item is LCFile) && item.IsDirty) .Cast <LCFile>(); foreach (LCFile file in dirtyFiles) { await file.Save(); } List <LCObject> dirtyObjects = batch.objects.Where(item => item.IsDirty) .ToList(); if (dirtyObjects.Count == 0) { continue; } List <Dictionary <string, object> > requestList = dirtyObjects.Select(item => { string path = item.ObjectId == null ? $"/1.1/classes/{item.ClassName}" : $"/1.1/classes/{item.ClassName}/{item.ClassName}"; string method = item.ObjectId == null ? "POST" : "PUT"; Dictionary <string, object> body = LCEncoder.Encode(item.operationDict) as Dictionary <string, object>; return(new Dictionary <string, object> { { "path", path }, { "method", method }, { "body", body } }); }).ToList(); Dictionary <string, object> data = new Dictionary <string, object> { { "requests", LCEncoder.Encode(requestList) } }; List <Dictionary <string, object> > results = await LCCore.HttpClient.Post <List <Dictionary <string, object> > >("batch", data : data); List <LCObjectData> resultList = results.Select(item => { if (item.TryGetValue("error", out object error)) { Dictionary <string, object> err = error as Dictionary <string, object>; int code = (int)err["code"]; string message = (string)err["error"]; throw new LCException(code, message as string); } return(LCObjectData.Decode(item["success"] as IDictionary)); }).ToList(); for (int i = 0; i < dirtyObjects.Count; i++) { LCObject obj = dirtyObjects[i]; LCObjectData objData = resultList[i]; obj.Merge(objData); } } }
/// <summary> /// Saves each object in the provided list. /// </summary> /// <param name="objects">The objects to save.</param> /// <returns></returns> public static async Task <List <LCObject> > SaveAll(IEnumerable <LCObject> objects) { if (objects == null) { throw new ArgumentNullException(nameof(objects)); } foreach (LCObject obj in objects) { if (LCBatch.HasCircleReference(obj, new HashSet <LCObject>())) { throw new ArgumentException("Found a circle dependency when save."); } } Stack <LCBatch> batches = LCBatch.BatchObjects(objects, true); await SaveBatches(batches); return(objects.ToList()); }
/// <summary> /// Saves this object to the cloud. /// </summary> /// <param name="fetchWhenSave">Whether or not fetch data when saved.</param> /// <param name="query">The condition for saving.</param> /// <returns></returns> public async Task <LCObject> Save(bool fetchWhenSave = false, LCQuery <LCObject> query = null) { if (LCBatch.HasCircleReference(this, new HashSet <LCObject>())) { throw new ArgumentException("Found a circle dependency when save."); } Stack <LCBatch> batches = LCBatch.BatchObjects(new List <LCObject> { this }, false); if (batches.Count > 0) { await SaveBatches(batches); } string path = ObjectId == null ? $"classes/{ClassName}" : $"classes/{ClassName}/{ObjectId}"; Dictionary <string, object> queryParams = new Dictionary <string, object>(); if (fetchWhenSave) { queryParams["fetchWhenSave"] = true; } if (query != null) { queryParams["where"] = query.BuildWhere(); } Dictionary <string, object> response = ObjectId == null ? await LCCore.HttpClient.Post <Dictionary <string, object> >(path, data : LCEncoder.Encode(operationDict) as Dictionary <string, object>, queryParams : queryParams) : await LCCore.HttpClient.Put <Dictionary <string, object> >(path, data : LCEncoder.Encode(operationDict) as Dictionary <string, object>, queryParams : queryParams); LCObjectData data = LCObjectData.Decode(response); Merge(data); return(this); }