示例#1
0
        public static bool DiffWith(this DataTable first, DataTable second, IEnumerable <string> primaryKeyColumns, IEnumerable <string> valueColumns, out DataTable matches)
        {
            matches = new DataTable();
            matches.Columns.Add("PkeyDelta", typeof(int));
            matches.Columns.Add("ValueDelta", typeof(int));
            matches.Columns.Add("OldRow", typeof(DataRow));
            matches.Columns.Add("NewRow", typeof(DataRow));
            bool ret        = false;
            var  firstRows  = first.GetRows();
            var  secondRows = second.GetRows();
            var  f          = firstRows.ToList();
            var  s          = secondRows.ToList();

            string[] pkeyColumnNames  = primaryKeyColumns.ToArray();
            string[] valueColumnNames = valueColumns.ToArray();
            var      secondIndex      = new TableIndex(second);
            Dictionary <DataRow, object> assertDictionary1 = first.GetRows().ToDictionaryDX(NULL); //these are to make sure no records are missing/lost/double removed/etc.
            Dictionary <DataRow, object> assertDictionary2 = second.GetRows().ToDictionaryDX(NULL);

            for (int pkeyDelta = 0; pkeyDelta < primaryKeyColumns.Count(); pkeyDelta++)
            {
                for (int valueDelta = 0; valueDelta < valueColumns.Count(); valueDelta++)
                {
                    List <int> removals = new List <int>();
                    for (int i = 0; i < f.Count; i++)
                    {
                        var     frow  = f[i];
                        DataRow found = FindFuzzyMatch(frow, pkeyDelta, valueDelta, pkeyColumnNames, valueColumnNames, secondIndex);
                        if (found != null)
                        {
                            matches.Rows.Add(pkeyDelta, valueDelta, frow, found);
                            assertDictionary2.Remove(found);
                            secondIndex.Remove(found);
                            removals.Add(i);
                        }
                    }
                    for (int i = removals.Count - 1; i >= 0; i--)
                    {
                        assertDictionary1.Remove(f[removals[i]]);
                        f.RemoveAt(removals[i]);
                    }
                    if (pkeyDelta == 0 && valueDelta == 0 && assertDictionary1.Count == 0 && assertDictionary2.Count == 0)
                    {
                        ret = true;
                    }
                }
            }

            for (int i = 0; i < f.Count; i++)
            {
                matches.Rows.Add(-1, -1, f[i], null);
                assertDictionary1.Remove(f[i]);
            }

            for (int i = 0; i < s.Count; i++)
            {
                matches.Rows.Add(-1, -1, null, s[i]);
                assertDictionary2.Remove(s[i]);
            }
            Debug.Assert(assertDictionary1.Count == 0);
            Debug.Assert(assertDictionary2.Count == 0);
            return(ret);
        }