我正在写一个简短的算法,该算法必须比较两个数据集,以便可以进一步处理两者之间的差异。
我尝试通过合并这两个DataSet并将最终的更改合并到一个新的DataSet中来实现此目标。

我的方法如下所示:

    private DataSet ComputateDiff(DataSet newVersion, DataSet oldVersion)
    {
        DataSet diff = null;
        oldVersion.Merge(newVersion);
        bool foundChanges = oldVersion.HasChanges();
        if (foundChanges)
        {
            diff = oldVersion.GetChanges();
        }
        return diff;
    }

即使两个数据集中的值不同,foundChanges的结果也始终为false。
两个数据集具有相同的结构。它们由三个数据表组成,这三个数据表是数据库中三个查询的结果。
合并工作正常,没有任何问题。

我的问题是:
是否有任何合理的解释,为什么foundChanges变量始终为false,如果不是,Linq是否可以为该问题提供适当的解决方案,或者我必须通过遍历DataSet来确定更改?

以下是一些其他信息:
编程语言是C#
我正在使用.Net Framework 4.0
我正在Windows 8计算机上进行开发
提到的数据来自数据库(MSSQL Server 2012 Express)
据我所知,我的数据集或数据表没有任何PK。

提前致谢

最佳答案

我认为问题在于您不了解.NET数据集。 DataTable保留加载到其中的每个值的“原始”副本。更改值时,DataTable能够检测到更改。同样,DataTable跟踪已添加或删除的行。 HasChanges()函数只是在DataTables中进行爬网,并检查是否有任何更改(更改的值,新行,已删除的行等)。

请参阅MSDN文档:
http://msdn.microsoft.com/en-us/library/system.data.dataset.haschanges.aspx

比较两个数据集非常棘手,而且我不知道有任何内置函数可以处理此问题(因为每个程序员都有自己的“等效性”定义)。

看:

StackOverflow上的

  • How to compare 2 dataTables
  • CodeProject上的
  • Comparing DataSets using LINQ

  • 下面的代码将通过基于Key列查找添加/删除的行来比较两个DataTables,并通过比较匹配行的值(同样基于键)来查找修改的行。将其扩展为比较数据集(通过比较数据集之间的类似名称的表)将是相当琐碎的。
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    
    namespace DataSetComparison
    {
        class Program
        {
            static void Main( string[] args )
            {
    
                var l_table1 = new DataTable();
                l_table1.Columns.Add( "Key", typeof( int ) );
                l_table1.Columns.Add( "Name", typeof( string ) );
                l_table1.Columns.Add( "Age", typeof( int ) );
    
                var l_table2 = new DataTable();
                l_table2.Columns.Add( "Key", typeof( int ) );
                l_table2.Columns.Add( "Name", typeof( string ) );
                l_table2.Columns.Add( "Age", typeof( int ) );
    
                l_table1.Rows.Add( l_table1.NewRow() );
                l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 0;
                l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Alfred Harisson";
                l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 36;
                l_table1.Rows.Add( l_table1.NewRow() );
                l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 1;
                l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Matthew George";
                l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 41;
                l_table1.Rows.Add( l_table1.NewRow() );
                l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 2;
                l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Franklin Henry";
                l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 33;
    
                l_table2.Rows.Add( l_table2.NewRow() );
                l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 0;
                l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Alfred Harisson";
                l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 36;
                l_table2.Rows.Add( l_table2.NewRow() );
                l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 1;
                l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Matthew George";
                l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 42; // Record 1 "modified"
                // Record 2 "deleted"
                // Record 3 "added":
                l_table2.Rows.Add( l_table2.NewRow() );
                l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 3;
                l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Lester Kulick";
                l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 33;
    
                // Using table 1 as the control, find changes in table 2
    
                // Find deleted rows:
                var l_table2Keys = l_table2.Select().Select( ( r ) => (int) r["Key"] );
                var l_deletedRows = l_table1.Select().Where( ( r ) => !l_table2Keys.Contains( (int) r["Key"] ) );
    
                foreach ( var l_deletedRow in l_deletedRows )
                    Console.WriteLine( "Record " + l_deletedRow["Key"].ToString() + " was deleted from table 2." );
    
                // Find added rows:
                var l_table1Keys = l_table1.Select().Select( ( r ) => (int) r["Key"] );
                var l_addedRows = l_table2.Select().Where( ( r ) => !l_table1Keys.Contains( (int) r["Key"] ) );
    
                foreach ( var l_addedRow in l_addedRows )
                    Console.WriteLine( "Record " + l_addedRow["Key"].ToString() + " was added to table 2." );
    
                // Find modified rows:
                var l_modifiedRows = l_table2.Select()
                                             .Join(
                                                l_table1.Select(),
                                                r => (int) r["Key"],
                                                r => (int) r["Key"],
                                                ( r1, r2 ) => new
                                                    {
                                                        Row1 = r1,
                                                        Row2 = r2
                                                    } )
                                            .Where(
                                                values => !( values.Row1["Name"].Equals( values.Row2["Name"] ) &&
                                                             values.Row1["Age"].Equals( values.Row2["Age"] ) ) )
                                            .Select( values => values.Row2 );
    
                foreach ( var l_modifiedRow in l_modifiedRows )
                    Console.WriteLine( "Record " + l_modifiedRow["Key"].ToString() + " was modified in table 2." );
    
                Console.WriteLine( "Press any key to quit..." );
                Console.ReadKey( true );
    
            }
        }
    }
    

    控制台输出:

    关于c# - 得到2个数据集C#中的差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14055909/

    10-12 19:08
    查看更多