C# 比较datarows和输出差异.net 4

C# 比较datarows和输出差异.net 4,c#,datatable,ado.net,datarow,C#,Datatable,Ado.net,Datarow,我已经有一段时间没有使用数据表了。 是否有一种方法可以让给定的2个数据表或1个数据表比较所有具有相同customerId的行,并输出已更改的字段名和行值 需要比较不同阶段的客户机数据,找出哪些值已更改 有什么建议吗 代码示例 更新。 我还没有发现一个关于stackoverflow的问题显示如何在两个表之间获得差异。 我的解决方案到目前为止,但需要找到一种方法来填充差异对象 //Now use Except operator to find the data in firs

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

需要比较不同阶段的客户机数据,找出哪些值已更改

有什么建议吗

代码示例

更新。 我还没有发现一个关于stackoverflow的问题显示如何在两个表之间获得差异。 我的解决方案到目前为止,但需要找到一种方法来填充差异对象

            //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; }
    }
}
//现在使用Except运算符查找第一个集合中的数据,而不是第二个集合中的数据
var userDataFirstSet=oldDt
.可计算的()
.Except(newDt.AsEnumerable(),DataRowComparer.Default);
//查找第二个数据,而不是第一个数据
var userDataSecondSet=newDt
.可计算的()
.Except(oldDt.AsEnumerable(),DataRowComparer.Default);
List dataRows=userDataFirstSet
.Union(userDataSecondSet)
.ToList();
//现在将所有的差异填入列表
Listdiffs=新列表();
使用制度;
使用System.Collections.Generic;
使用系统数据;
使用System.Linq;
使用系统文本;
命名空间控制台应用程序1
{
内部课程计划
{
私有静态void Main()
{
客户[]旧客户集=
{
新客户{CustomerId=1,Name=“Joe”,姓氏=“Bloggs”,City=“London”},
新客户{CustomerId=2,Name=“Mark”,姓氏=“Smith”,City=“Manchester”},
新客户{CustomerId=3,Name=“Emily”,姓氏=“Blunt”,City=“Liverpool”},
};
客户[]新客户集=
{
新客户{CustomerId=1,Name=“Joe”,姓氏=“Bloggs”,City=“London”},
新客户{CustomerId=2,Name=“Mark”,姓氏=“Smithyyy”,City=“Manchesteraaa”},
新客户{CustomerId=3,Name=“Emily”,姓氏=“Blunt”,City=“Liverpool”},
};
DataTable oldDt=GetDataTable(OldCustomerSet);
DataTable newDt=GetDataTable(NewCustomerSet);
//比较每个customerId的2个数据表,并返回值不同的ColumnName。
差值diff=比较器ows(oldDt,newDt);
/*
//想要的结果是
差异差异=新的差异();
差异客户ID=2;
diff.FieldName=“姓氏”;
diff.OldDataRowValue=“Smith”;
diff.NewDataRowValue=“Smithyyy”
*/
}
专用静态差异比较程序(DataTable oldDt、DataTable newDt)
{
差异差异=新的差异();
//理想情况下,是一种查找不同行值的通用方法,无需硬编码行名。
返回差;
}
私有静态数据表GetDataTable(客户[]客户)
{
DataTable=新的DataTable();
表.Columns.Add(“CustomerId”,typeof(Int32));
表.列.添加(“名称”,类型(字符串));
表.列.添加(“姓氏”,类型(字符串));
表.列.添加(“城市”,类型(字符串));
foreach(客户中的客户)
{
table.Rows.Add(customer.CustomerId,
客户名称,
顾客,姓,,
客户(城市);
}
返回(表);
}
}
公共类客户
{
public int CustomerId{get;set;}
公共字符串名称{get;set;}
公共字符串姓氏{get;set;}
公共字符串City{get;set;}
}
公共阶级差异
{
public int CustomerId{get;set;}
公共字符串字段名{get;set;}
公共字符串OldDataRowValue{get;set;}
公共字符串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) });
        }
    }
}

抱歉的可能重复即使标题暗示,这也不是重复。这里没有返回差异的解决方案。它只返回真或假。不要太快地说“这是重复的!谢谢你的时间和回答。有点接近,我唯一不喜欢的是我们正在硬编码”customerId“。我自己制定了一个不同的解决方案,但需要找到忽略某些字段的方法。var userDataFirstSet=oldDt.aseneumerable()。除了(newDt.aseneumerable(),DataRowComparer.Default)//在第二个变量userDataSecondSet=newDt.aseneumerable()中查找数据,而不是在第一个变量中查找数据(oldDt.aseneumerable(),DataRowComparer.Default);List dataRows=userDataFirstSet.Union(userDataSecondSet.ToList();仍然没有,因为我需要填写一个不同对象的列表“更新的问题”
CustomerID | FieldName | OldDataRowValue | NewDataRowValue
2          | Surname   | Smith           | Smithyyy
2          | City      | Manchester      | Manchesteraaa