Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何比较2个数据表_C#_.net_Datatable - Fatal编程技术网

C# 如何比较2个数据表

C# 如何比较2个数据表,c#,.net,datatable,C#,.net,Datatable,我有两个数据表,我只想知道它们是否相同。我所说的“相同”,是指它们的行数是否完全相同,每列中的数据是否完全相同。我想写(找到)一个方法,它接受两个表并返回一个布尔值 如何以这种方式比较两个数据表?两者都有相同的模式。没有任何东西可以为您这样做;完成此操作的唯一方法是迭代所有行/列并相互比较。您需要遍历每个表的行,然后遍历该循环中的每列以比较各个值 这里有一个代码示例:如果数据库中有表,则可以进行完整的外部联接以获得差异。例如: select t1.Field1, t1.Field2, t2.Fi

我有两个数据表,我只想知道它们是否相同。我所说的“相同”,是指它们的行数是否完全相同,每列中的数据是否完全相同。我想写(找到)一个方法,它接受两个表并返回一个布尔值


如何以这种方式比较两个数据表?两者都有相同的模式。

没有任何东西可以为您这样做;完成此操作的唯一方法是迭代所有行/列并相互比较。

您需要遍历每个表的行,然后遍历该循环中的每列以比较各个值


这里有一个代码示例:

如果数据库中有表,则可以进行完整的外部联接以获得差异。例如:

select t1.Field1, t1.Field2, t2.Field1, t2.Field2
from Table1 t1
full outer join Table2 t2 on t1.Field1 = t2.Field1 and t1.Field2 = t2.Field2
where t1.Field1 is null or t2.Field2 is null

将过滤掉所有相同的记录。前两个或后两个字段中都有数据,这取决于记录来自哪个表。

尝试使用linq to数据集

(from b in table1.AsEnumerable()  
    select new { id = b.Field<int>("id")}).Except(
         from a in table2.AsEnumerable() 
             select new {id = a.Field<int>("id")})
(来自表1.AsEnumerable()中的b)
选择新的{id=b.Field(“id”)})(
来自表2中的a.AsEnumerable()
选择新{id=a.Field(“id”)})
检查本文:

公共静态bool是相同的(数据表tbl1,数据表tbl2)
{
if(tbl1.Rows.Count!=tbl2.Rows.Count | | tbl1.Columns.Count!=tbl2.Columns.Count)
返回false;
对于(int i=0;i
或者,我没有实现数组比较,因此您也会有一些乐趣:)

公共布尔比较表(数据表a、数据表b)
{
如果(a.Rows.Count!=b.Rows.Count)
{
//不同的尺寸意味着不同的桌子
返回false;
}

对于(int rowIndex=0;rowIndex如果您使用的是一个数据表,那么您是否可以将加载时将要发生更改的数据表与原始数据进行比较呢

我使用它并编写了一个公共方法来调用代码并返回布尔值

OP的答案:

使用的代码:

public bool tablesAreTheSame(DataTable table1, DataTable table2)
{
    DataTable dt;
    dt = getDifferentRecords(table1, table2);

    if (dt.Rows.Count == 0)
        return true;
    else
        return false;
}

//Found at http://canlu.blogspot.com/2009/05/how-to-compare-two-datatables-in-adonet.html
private DataTable getDifferentRecords(DataTable FirstDataTable, DataTable SecondDataTable)
{
    //Create Empty Table     
    DataTable ResultDataTable = new DataTable("ResultDataTable");

    //use a Dataset to make use of a DataRelation object     
    using (DataSet ds = new DataSet())
    {
        //Add tables     
        ds.Tables.AddRange(new DataTable[] { FirstDataTable.Copy(), SecondDataTable.Copy() });

        //Get Columns for DataRelation     
        DataColumn[] firstColumns = new DataColumn[ds.Tables[0].Columns.Count];
        for (int i = 0; i < firstColumns.Length; i++)
        {
            firstColumns[i] = ds.Tables[0].Columns[i];
        }

        DataColumn[] secondColumns = new DataColumn[ds.Tables[1].Columns.Count];
        for (int i = 0; i < secondColumns.Length; i++)
        {
            secondColumns[i] = ds.Tables[1].Columns[i];
        }

        //Create DataRelation     
        DataRelation r1 = new DataRelation(string.Empty, firstColumns, secondColumns, false);
        ds.Relations.Add(r1);

        DataRelation r2 = new DataRelation(string.Empty, secondColumns, firstColumns, false);
        ds.Relations.Add(r2);

        //Create columns for return table     
        for (int i = 0; i < FirstDataTable.Columns.Count; i++)
        {
            ResultDataTable.Columns.Add(FirstDataTable.Columns[i].ColumnName, FirstDataTable.Columns[i].DataType);
        }

        //If FirstDataTable Row not in SecondDataTable, Add to ResultDataTable.     
        ResultDataTable.BeginLoadData();
        foreach (DataRow parentrow in ds.Tables[0].Rows)
        {
            DataRow[] childrows = parentrow.GetChildRows(r1);
            if (childrows == null || childrows.Length == 0)
                ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
        }

        //If SecondDataTable Row not in FirstDataTable, Add to ResultDataTable.     
        foreach (DataRow parentrow in ds.Tables[1].Rows)
        {
            DataRow[] childrows = parentrow.GetChildRows(r2);
            if (childrows == null || childrows.Length == 0)
                ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
        }
        ResultDataTable.EndLoadData();
    }

    return ResultDataTable;
}
公共布尔表相同(数据表表1、数据表2)
{
数据表dt;
dt=获取不同记录(表1、表2);
如果(dt.Rows.Count==0)
返回true;
其他的
返回false;
}
//发现于http://canlu.blogspot.com/2009/05/how-to-compare-two-datatables-in-adonet.html
专用数据表getDifferentRecords(DataTable FirstDataTable、DataTable SecondDataTable)
{
//创建空表
DataTable ResultDataTable=新数据表(“ResultDataTable”);
//使用数据集使用DataRelation对象
使用(数据集ds=新数据集())
{
//添加表
AddRange(新数据表[]{FirstDataTable.Copy(),SecondDataTable.Copy()});
//获取DataRelation的列
DataColumn[]firstColumns=新的DataColumn[ds.Tables[0].Columns.Count];
for(int i=0;i

如果将数据表作为函数返回,则可以:

DataTable dataTable1; // Load with data
DataTable dataTable2; // Load with data (same schema)

// Fast check for row count equality.
if ( dataTable1.Rows.Count != dataTable2.Rows.Count) {
    return true;
}

var differences =
    dataTable1.AsEnumerable().Except(dataTable2.AsEnumerable(),
                                            DataRowComparer.Default);

return differences.Any() ? differences.CopyToDataTable() : new DataTable();
//
/// https://stackoverflow.com/a/45620698/2390270
///比较源数据表和目标数据表,并返回相同、不同、添加和删除的行
/// 
///要比较的数据表
///要与dtOld进行比较的数据表
///DataTable,它将为您提供两个数据库中的公共行
///数据表,这将给你的区别
///将为您提供从dtOld到dtNew添加的行的DataTable
///将为您提供从dtOld到dtNew删除的行的DataTable
公共静态void GetTableDiff(DataTable dtOld、DataTable dtNew、ref DataTable dtSame、ref DataTable dtDifferences、ref DataTable dtAdded、ref DataTable dtRemoved)
{
尝试
{
dtAdded=dtOld.Clone();
dtAdded.Clear();
dtRemoved=dtOld.Clone();
dtRemoved.Clear();
dtSame=dtO
public bool tablesAreTheSame(DataTable table1, DataTable table2)
{
    DataTable dt;
    dt = getDifferentRecords(table1, table2);

    if (dt.Rows.Count == 0)
        return true;
    else
        return false;
}

//Found at http://canlu.blogspot.com/2009/05/how-to-compare-two-datatables-in-adonet.html
private DataTable getDifferentRecords(DataTable FirstDataTable, DataTable SecondDataTable)
{
    //Create Empty Table     
    DataTable ResultDataTable = new DataTable("ResultDataTable");

    //use a Dataset to make use of a DataRelation object     
    using (DataSet ds = new DataSet())
    {
        //Add tables     
        ds.Tables.AddRange(new DataTable[] { FirstDataTable.Copy(), SecondDataTable.Copy() });

        //Get Columns for DataRelation     
        DataColumn[] firstColumns = new DataColumn[ds.Tables[0].Columns.Count];
        for (int i = 0; i < firstColumns.Length; i++)
        {
            firstColumns[i] = ds.Tables[0].Columns[i];
        }

        DataColumn[] secondColumns = new DataColumn[ds.Tables[1].Columns.Count];
        for (int i = 0; i < secondColumns.Length; i++)
        {
            secondColumns[i] = ds.Tables[1].Columns[i];
        }

        //Create DataRelation     
        DataRelation r1 = new DataRelation(string.Empty, firstColumns, secondColumns, false);
        ds.Relations.Add(r1);

        DataRelation r2 = new DataRelation(string.Empty, secondColumns, firstColumns, false);
        ds.Relations.Add(r2);

        //Create columns for return table     
        for (int i = 0; i < FirstDataTable.Columns.Count; i++)
        {
            ResultDataTable.Columns.Add(FirstDataTable.Columns[i].ColumnName, FirstDataTable.Columns[i].DataType);
        }

        //If FirstDataTable Row not in SecondDataTable, Add to ResultDataTable.     
        ResultDataTable.BeginLoadData();
        foreach (DataRow parentrow in ds.Tables[0].Rows)
        {
            DataRow[] childrows = parentrow.GetChildRows(r1);
            if (childrows == null || childrows.Length == 0)
                ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
        }

        //If SecondDataTable Row not in FirstDataTable, Add to ResultDataTable.     
        foreach (DataRow parentrow in ds.Tables[1].Rows)
        {
            DataRow[] childrows = parentrow.GetChildRows(r2);
            if (childrows == null || childrows.Length == 0)
                ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
        }
        ResultDataTable.EndLoadData();
    }

    return ResultDataTable;
}
DataTable dataTable1; // Load with data
DataTable dataTable2; // Load with data (same schema)

// Fast check for row count equality.
if ( dataTable1.Rows.Count != dataTable2.Rows.Count) {
    return true;
}

var differences =
    dataTable1.AsEnumerable().Except(dataTable2.AsEnumerable(),
                                            DataRowComparer.Default);

return differences.Any() ? differences.CopyToDataTable() : new DataTable();
    /// <summary>
    /// https://stackoverflow.com/a/45620698/2390270
    /// Compare a source and target datatables and return the row that are the same, different, added, and removed
    /// </summary>
    /// <param name="dtOld">DataTable to compare</param>
    /// <param name="dtNew">DataTable to compare to dtOld</param>
    /// <param name="dtSame">DataTable that would give you the common rows in both</param>
    /// <param name="dtDifferences">DataTable that would give you the difference</param>
    /// <param name="dtAdded">DataTable that would give you the rows added going from dtOld to dtNew</param>
    /// <param name="dtRemoved">DataTable that would give you the rows removed going from dtOld to dtNew</param>
    public static void GetTableDiff(DataTable dtOld, DataTable dtNew, ref DataTable dtSame, ref DataTable dtDifferences, ref DataTable dtAdded, ref DataTable dtRemoved)
    {
        try
        {
            dtAdded = dtOld.Clone();
            dtAdded.Clear();
            dtRemoved = dtOld.Clone();
            dtRemoved.Clear();
            dtSame = dtOld.Clone();
            dtSame.Clear();
            if (dtNew.Rows.Count > 0) dtDifferences.Merge(dtNew.AsEnumerable().Except(dtOld.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>());
            if (dtOld.Rows.Count > 0) dtDifferences.Merge(dtOld.AsEnumerable().Except(dtNew.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>());
            if (dtOld.Rows.Count > 0 && dtNew.Rows.Count > 0) dtSame = dtOld.AsEnumerable().Intersect(dtNew.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>();
            foreach (DataRow row in dtDifferences.Rows)
            {
                if (dtOld.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray))
                    && !dtNew.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray)))
                {
                    dtRemoved.Rows.Add(row.ItemArray);
                }
                else if (dtNew.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray))
                    && !dtOld.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray)))
                {
                    dtAdded.Rows.Add(row.ItemArray);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
    }
public class DataTableComparer : IEqualityComparer<DataRow>
{
    private IEnumerable<String> g_TestColumns;
    public void SetCompareColumns(IEnumerable<String> p_Columns)
    {
        g_TestColumns = p_Columns; 
    }

    public bool Equals(DataRow x, DataRow y)
    {

        foreach (String sCol in g_TestColumns)
            if (!x[sCol].Equals(y[sCol])) return false;

        return true;
    }

    public int GetHashCode(DataRow obj)
    {
        StringBuilder hashBuff = new StringBuilder();

        foreach (String sCol in g_TestColumns)
            hashBuff.AppendLine(obj[sCol].ToString());               

        return hashBuff.ToString().GetHashCode();

    }
}
DataTableComparer comp = new DataTableComparer();
comp.SetCompareColumns(new String[] { "Name", "DoB" });

DataTable celebrities = SomeDataTableSource();
DataTable politicians = SomeDataTableSource2();

List<DataRow> celebrityPoliticians = celebrities.AsEnumerable().Intersect(politicians.AsEnumerable(), comp).ToList();
public DataTable GetTwoDataTablesChanges(DataTable firstDataTable, DataTable secondDataTable)
{ 
     firstDataTable.Merge(secondDataTable);
     return secondDataTable.GetChanges();
}