比较数据行和输出差异.net 4

Comparing datarows and output difference .net 4

我有一段时间没有使用数据表了。 有没有一种方法可以给定 2 个数据表甚至 1 个比较具有相同 customerId 的所有行并输出已更改的字段名和行值。

需要对比客户各个阶段的数据,找出哪些值发生了变化。

有什么建议吗?

代码示例

已更新。 我没有在 Whosebug 上找到一个显示如何区分 2 个表的问题。 到目前为止我的解决方案但需要找到一种方法来填充差异对象

            //Now use Except operator to find the data in first set and not in second
        var userDataFirstSet = oldDt
            .AsEnumerable()
            .Except(newDt.AsEnumerable(), DataRowComparer.Default);

        //Find data in second and not in first
        var userDataSecondSet = newDt
            .AsEnumerable()
            .Except(oldDt.AsEnumerable(),DataRowComparer.Default);


        List<DataRow> dataRows = userDataFirstSet
            .Union(userDataSecondSet)
            .ToList();

        //Now fill the list with all the differences
       List<Difference>diffs=new List<Difference>();


using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main()
        {
            Customer[] oldCustomersSet =
            {
                new Customer {CustomerId = 1, Name = "Joe", Surname = "Bloggs", City = "London"},
                new Customer {CustomerId = 2, Name = "Mark", Surname = "Smith", City = "Manchester"},
                new Customer {CustomerId = 3, Name = "Emily", Surname = "Blunt", City = "Liverpool"},
            };

            Customer[] newCustomersSet =
            {
                new Customer {CustomerId = 1, Name = "Joe", Surname = "Bloggs", City = "London"},
                new Customer {CustomerId = 2, Name = "Mark", Surname = "Smithyyy", City = "Manchesteraaa"},
                new Customer {CustomerId = 3, Name = "Emily", Surname = "Blunt", City = "Liverpool"},
            };

            DataTable oldDt = GetDataTable(oldCustomersSet);
            DataTable newDt = GetDataTable(newCustomersSet);

            //compare the 2 datatables for each customerId and return ColumnName where the value is different.
            Difference diff=CompareRows(oldDt, newDt);

            /*
           //wanted result is
           Difference diff=new Difference();
           diff.CustomerId = 2;
           diff.FieldName = "Surname";
           diff.OldDataRowValue = "Smith";
           diff.NewDataRowValue = "Smithyyy"
            */

        }

        private static Difference CompareRows(DataTable oldDt, DataTable newDt)
        {
            Difference diff=new Difference();

            //Ideally a generic way to find row values that are different without hardcode the rowName.



            return diff;
        }

        private static DataTable GetDataTable(Customer[] customers)
        {
            DataTable table = new DataTable();

            table.Columns.Add("CustomerId", typeof(Int32));
            table.Columns.Add("Name", typeof(string));
            table.Columns.Add("Surname", typeof(string));
            table.Columns.Add("City", typeof(string));

            foreach (Customer customer in customers)
            {
                table.Rows.Add(customer.CustomerId,
                    customer.Name,
                    customer.Surname,
                    customer.City);
            }

            return (table);
        }

    }

    public class Customer
    {
        public int CustomerId { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
        public string City { get; set; }
    }

    public class Difference
    {
        public int CustomerId { get; set; }
        public string FieldName { get; set; }
        public string OldDataRowValue { get; set; }
        public string NewDataRowValue { get; set; }
    }
}

为什么不只遍历行、遍历列并查找差异呢?我认为库中没有内置解决方案。

var joined = oldDt.AsEnumerable().Join(newDt.AsEnumerable(), dr => dr.Field<int>("CustomerId"), dr => dr.Field<int>("CustomerId"), (da, db) => Tuple.Create(da, db)).ToList();
var differences = new List<Difference>();
foreach (var entry in joined) {
    var customerId = entry.Item1.Field<int>("CustomerId");
    foreach (var column in oldDt.Columns.Cast<DataColumn>()) {
        var oldVal = entry.Item1[column.ColumnName];
        var newVal = entry.Item2[column.ColumnName];
        if (!object.Equals(oldVal, newVal)) {
            differences.Add(new Difference { CustomerId = customerId, FieldName = column.ColumnName, OldDataRowValue = Convert.ToString(oldVal), NewDataRowValue = Convert.ToString(newVal) });
        }
    }
}

differences 的输出:

CustomerID | FieldName | OldDataRowValue | NewDataRowValue
2          | Surname   | Smith           | Smithyyy
2          | City      | Manchester      | Manchesteraaa