我正在尝试比较两个Json数组,并且仅获取数组中的更改或差异。想法是只将新记录插入数据库。
基于以下链接的belwo实现
https://www.experts-exchange.com/questions/29044077/Compare-to-json-string-in-c-and-get-results.html
https://code.i-harness.com/en/q/17b9432
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
string newData = string.Empty;
JObject newDataJObject = null;
string oldData = string.Empty;
JObject oldDataJObject = null;
newData="{"RECORDS":[{"ENGINE":"JZMBVB23034","CHASSIS":"MD2DSJZZZVWB78384","PRODH":"DISCOVER","LANDX":"BANGLADESH","AUART":"ZVEX","WADAT_IST":null},{"ENGINE":"PFZWJL61018","CHASSIS":"","PRODH":"BOXER","LANDX":"EGYPT","AUART":"ZVKP","WADAT_IST":null},{"ENGINE":"JZMBVB23035","CHASSIS":"MD2DSJZZZVWB78384","PRODH":"DISCOVER","LANDX":"BANGLADESH","AUART":"ZVKP","WADAT_IST":null}]}"
newDataJObject=JObject.Parse(newData);
oldData="{"RECORDS":[{"ENGINE":"JZMB23034","CHASSIS":"MD2DSJZZVWB78384","PRODH":"DISCOVER","LANDX":"BANGLADESH","AUART":"ZVEX","WADAT_IST":null},{"ENGINE":"PFZW61018","CHASSIS":"","PRODH":"BOXER","LANDX":"EGYPT","AUART":"ZVKP","WADAT_IST":null}]}";
oldDataJObject = JObject.Parse(oldData);
bool result = JToken.DeepEquals(newDataJObject, oldDataJObject);
StringBuilder returnString = new StringBuilder();
returnString = CompareObjects(newDataJObject, oldDataJObject);
private static StringBuilder CompareObjects(JObject source, JObject target)
{
StringBuilder returnString = new StringBuilder();
foreach (KeyValuePair<string, JToken> sourcePair in source)
{
if (sourcePair.Value.Type == JTokenType.Object)
{
if (target.GetValue(sourcePair.Key) == null)
{
returnString.Append("Key " + sourcePair.Key
+ " not found" + Environment.NewLine);
}
else if (target.GetValue(sourcePair.Key).Type != JTokenType.Object)
{
returnString.Append("Key " + sourcePair.Key
+ " is not an object in target" + Environment.NewLine);
}
else
{
returnString.Append(CompareObjects(sourcePair.Value.ToObject<JObject>(),
target.GetValue(sourcePair.Key).ToObject<JObject>()));
}
}
else if (sourcePair.Value.Type == JTokenType.Array)
{
if (target.GetValue(sourcePair.Key) == null)
{
returnString.Append("Key " + sourcePair.Key
+ " not found" + Environment.NewLine);
}
else
{
returnString.Append(CompareArrays(sourcePair.Value.ToObject<JArray>(),
target.GetValue(sourcePair.Key).ToObject<JArray>(), sourcePair.Key));
}
}
else
{
JToken expected = sourcePair.Value;
var actual = target.SelectToken(sourcePair.Key);
if (actual == null)
{
returnString.Append("Key " + sourcePair.Key
+ " not found" + Environment.NewLine);
}
else
{
if (!JToken.DeepEquals(expected, actual))
{
// todo:logic to get the difference here only
returnString.Append("Key " + sourcePair.Key + ": "
+ sourcePair.Value + " != "
+ target.Property(sourcePair.Key).Value
+ Environment.NewLine);
}
}
}
}
return returnString;
}
private static StringBuilder CompareArrays(JArray source, JArray target, string arrayName = "")
{
var returnString = new StringBuilder();
for (var index = 0; index < source.Count; index++)
{
var expected = source[index];
if (expected.Type == JTokenType.Object)
{
var actual = (index >= target.Count) ? new JObject() : target[index];
returnString.Append(CompareObjects(expected.ToObject<JObject>(),
actual.ToObject<JObject>()));
}
else
{
var actual = (index >= target.Count) ? "" : target[index];
if (!JToken.DeepEquals(expected, actual))
{
if (String.IsNullOrEmpty(arrayName))
{
returnString.Append("Index " + index + ": " + expected
+ " != " + actual + Environment.NewLine);
}
else
{
returnString.Append("Key " + arrayName
+ "[" + index + "]: " + expected
+ " != " + actual + Environment.NewLine);
}
}
}
}
return returnString;
}
现在我想要的预期结果是仅获得像这样的数组对象中的更改
{
"ENGINE": "JZMBVB23035",
"CHASSIS": "MD2DSJZZZVWB78384",
"PRODH": "DISCOVER",
"LANDX": "Bangladesh",
"AUART": "ZVKP"
}
任何帮助将不胜感激。
谢谢
开发
答案 0 :(得分:2)
您可以反序列化两个Json,然后比较列表。例如,
public class RECORD
{
public string ENGINE { get; set; }
public string CHASSIS { get; set; }
public string PRODH { get; set; }
public string LANDX { get; set; }
public string AUART { get; set; }
public object WADAT_IST { get; set; }
}
public class RootObject
{
public List<RECORD> RECORDS { get; set; }
}
使用上述数据结构,我们可以按如下方法反序列化。
var newDataList = JsonConvert.DeserializeObject<RootObject>(newData);
var oldDataList = JsonConvert.DeserializeObject<RootObject>(oldData);
现在我们可以找到以下差异
var result = newDataList.RECORDS.Except(oldDataList.RECORDS)
答案 1 :(得分:0)
借助以上文章并使用了InitializationKeysComparer类。然后就像魅力
List<RECORDS> dataToInsert = objNewData.Except(objOldData, new InitializationKeysComparer()).ToList();
public class InitializationKeysComparer : IEqualityComparer<RECORDS>
{
public bool Equals(RECORDS x, RECORDS y)
{
return (x.ENGINE.Trim().Equals(y.ENGINE.Trim()) && x.PRODH.Trim().Equals(y.PRODH.Trim())&& x.LANDX.Trim().Equals(y.LANDX.Trim()));
}
public int GetHashCode(RECORDS obj)
{
return 0;
}
}
答案 2 :(得分:0)
可能这就是您想要的,不是吗?
var newData = @"{""RECORDS"":[{""ENGINE"":""JZMBVB23034"",""CHASSIS"":""MD2DSJZZZVWB78384"",""PRODH"":""DISCOVER"",""LANDX"":""BANGLADESH"",""AUART"":""ZVEX"",""WADAT_IST"":null},{""ENGINE"":""PFZWJL61018"",""CHASSIS"":"""",""PRODH"":""BOXER"",""LANDX"":""EGYPT"",""AUART"":""ZVKP"",""WADAT_IST"":null},{""ENGINE"":""JZMBVB23035"",""CHASSIS"":""MD2DSJZZZVWB78384"",""PRODH"":""DISCOVER"",""LANDX"":""BANGLADESH"",""AUART"":""ZVKP"",""WADAT_IST"":null}]}";
var oldData = @"{""RECORDS"":[{""ENGINE"":""JZMB23034"",""CHASSIS"":""MD2DSJZZVWB78384"",""PRODH"":""DISCOVER"",""LANDX"":""BANGLADESH"",""AUART"":""ZVEX"",""WADAT_IST"":null},{""ENGINE"":""PFZW61018"",""CHASSIS"":"""",""PRODH"":""BOXER"",""LANDX"":""EGYPT"",""AUART"":""ZVKP"",""WADAT_IST"":null}]}";
var newDataJObject = JObject.Parse(newData);
var oldDataJObject = JObject.Parse(oldData);
var diff = JsonDiffer.JsonDifferentiator.Differentiate(oldDataJObject, newDataJObject);
结果
{
"*RECORDS": [
{
"*ENGINE": "JZMB23034",
"*CHASSIS": "MD2DSJZZVWB78384"
},
{
"*ENGINE": "PFZW61018"
},
{
"+ENGINE": "JZMBVB23035",
"+CHASSIS": "MD2DSJZZZVWB78384",
"+PRODH": "DISCOVER",
"+LANDX": "BANGLADESH",
"+AUART": "ZVKP",
"+WADAT_IST": null
}
]
}