比较C#中的两个json数组,仅获取单独对象中的差异

时间:2019-01-28 10:54:54

标签: c# arrays linq json.net

我正在尝试比较两个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"
    }

任何帮助将不胜感激。

谢谢

开发

3 个答案:

答案 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
      }
   ]
}

https://www.nuget.org/packages/JsonDiffer