diff --git a/Storage/Storage.Test/ObjectTest.cs b/Storage/Storage.Test/ObjectTest.cs index 399f2af..1d0f92b 100644 --- a/Storage/Storage.Test/ObjectTest.cs +++ b/Storage/Storage.Test/ObjectTest.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using LeanCloud; using LeanCloud.Storage; +using static NUnit.Framework.TestContext; + namespace Storage.Test { public class ObjectTest { [SetUp] @@ -144,5 +146,25 @@ namespace Storage.Test { TestContext.WriteLine(hello["content"]); Assert.IsNull(hello["content"]); } + + [Test] + public async Task OperateNullProperty() { + LCObject obj = new LCObject("Hello"); + obj.Increment("intValue", 123); + obj.Increment("intValue", 321); + obj.Add("intList", 1); + obj.Add("intList", 2); + obj.Add("intList", 3); + await obj.Save(); + + WriteLine(obj["intValue"]); + Assert.AreEqual(obj["intValue"], 444); + List intList = obj["intList"] as List; + WriteLine(intList.Count); + Assert.AreEqual(intList.Count, 3); + Assert.AreEqual(intList[0], 1); + Assert.AreEqual(intList[1], 2); + Assert.AreEqual(intList[2], 3); + } } } diff --git a/Storage/Storage/Internal/Operation/LCAddOperation.cs b/Storage/Storage/Internal/Operation/LCAddOperation.cs index 0d1ae4d..9591e65 100644 --- a/Storage/Storage/Internal/Operation/LCAddOperation.cs +++ b/Storage/Storage/Internal/Operation/LCAddOperation.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using LeanCloud.Storage.Internal.Codec; namespace LeanCloud.Storage.Internal.Operation { @@ -16,11 +17,15 @@ namespace LeanCloud.Storage.Internal.Operation { return previousOp; } if (previousOp is LCAddOperation addOp) { - valueList.AddRange(addOp.valueList); + List list = new List(addOp.valueList); + list.AddRange(valueList); + valueList = list; return this; } if (previousOp is LCAddUniqueOperation addUniqueOp) { - valueList.AddRange(addUniqueOp.values); + List list = addUniqueOp.values.ToList(); + list.AddRange(valueList); + valueList = list; return this; } throw new ArgumentException("Operation is invalid after previous operation."); diff --git a/Storage/Storage/Internal/Operation/LCRemoveOperation.cs b/Storage/Storage/Internal/Operation/LCRemoveOperation.cs index 4a2f57a..bf75437 100644 --- a/Storage/Storage/Internal/Operation/LCRemoveOperation.cs +++ b/Storage/Storage/Internal/Operation/LCRemoveOperation.cs @@ -17,7 +17,10 @@ namespace LeanCloud.Storage.Internal.Operation { return previousOp; } if (previousOp is LCRemoveOperation removeOp) { - valueList.AddRange(removeOp.valueList); + List list = new List(removeOp.valueList); + list.AddRange(valueList); + valueList = list; + return this; } throw new ArgumentException("Operation is invalid after previous operation."); } @@ -30,7 +33,10 @@ namespace LeanCloud.Storage.Internal.Operation { } public object Apply(object oldValue, string key) { - List list = new List(oldValue as IEnumerable); + List list = new List(); + if (oldValue != null) { + list.AddRange(oldValue as IEnumerable); + } list.RemoveAll(item => valueList.Contains(item)); return list; } diff --git a/Storage/Storage/LCObject.cs b/Storage/Storage/LCObject.cs index c61cd33..b99e7d6 100644 --- a/Storage/Storage/LCObject.cs +++ b/Storage/Storage/LCObject.cs @@ -420,11 +420,6 @@ namespace LeanCloud.Storage { } void ApplyOperation(string key, ILCOperation op) { - if (operationDict.TryGetValue(key, out ILCOperation previousOp)) { - operationDict[key] = op.MergeWithPrevious(previousOp); - } else { - operationDict[key] = op; - } if (op is LCDeleteOperation) { estimatedData.Remove(key); } else { @@ -434,6 +429,11 @@ namespace LeanCloud.Storage { estimatedData[key] = op.Apply(null, key); } } + if (operationDict.TryGetValue(key, out ILCOperation previousOp)) { + operationDict[key] = op.MergeWithPrevious(previousOp); + } else { + operationDict[key] = op; + } } internal void Merge(LCObjectData objectData) {