22

我有这两个数据表,我想了解它们之间的区别。这是一个例子:

Table1
-------------------------
ID  |   Name 
--------------------------
 1  |  A
 2  |  B
 3  |  C
--------------------------

Table2
-------------------------
ID  |   Name 
--------------------------
 1  |  A
 2  |  B
--------------------------

我只想将结果作为 table1 中的数据而不是 table2 (table1-table2)

ResultTable
-------------------------
ID  |   Name 
--------------------------
 3  |  C
--------------------------

我尝试通过 Linq 使用这两个类似的解决方案,但它总是返回 table1 而不是 table1-table2。这是第一个解决方案:

DataTable table1= ds.Tables["table1"];
DataTable table2= ds.Tables["table2"];
var diff= table1.AsEnumerable().Except(table2.AsEnumerable(),DataRowComparer.Default);

第二种解决方案:

var dtOne = table1.AsEnumerable();
var dtTwo = table2.AsEnumerable();
var difference = dtOne.Except(dtTwo);

那么,错在哪里呢?非常感谢您的所有回答。:)

4

8 回答 8

7

你可以试试下面的代码...

table1.AsEnumerable().Where(
    r =>!table2.AsEnumerable().Select(x=>x["ID"]).ToList().Contains(r["ID"])).ToList();
于 2013-02-21T12:58:00.357 回答
5

我刚刚经历了这个,想分享我的发现。对于我的应用程序,它是一种数据同步机制,但我认为您会看到这如何应用于原始问题。

就我而言,我有一个DataTable代表我上次数据上传的数据,并且在将来的某个时候,我需要获取数据的当前状态并且只上传差异。

//  get the Current state of the data
DataTable dtCurrent = GetCurrentData();

//  get the Last uploaded data
DataTable dtLast = GetLastUploadData();
dtLast.AcceptChanges();

//  the table meant to hold only the differences
DataTable dtChanges = null;

//  merge the Current DataTable into the Last DataTable, 
//  with preserve changes set to TRUE
dtLast.Merge(dtCurrent, true);

//  invoke GetChanges() with DataRowState.Unchanged
//    !! this is the key !!
//    the rows with RowState == DataRowState.Unchanged 
//    are the differences between the 2 tables
dtChanges = dtLast.GetChanges(DataRowState.Unchanged);

我希望这有帮助。我为此奋斗了几个小时,在interwebz上发现了很多假线索,最后RowStates在合并了几种不同的方式后进行了比较

于 2014-09-03T04:02:57.160 回答
1

我将尝试在列级别而不是 DataTable 上执行此操作。

IEnumerable<int> id_table1 = table1.AsEnumerable().Select(val=> (int)val["ID"]);
IEnumerable<int> id_table2  = table2.AsEnumerable().Select(val=> (int)val["ID"]);
IEnumerable<int> id_notinTable1= id_table2.Except(id_table1);

只需.Select()在您的答案中添加一个...

于 2013-02-21T13:01:12.370 回答
1

Try below, this is pretty basic. Merge two sets together, and get the difference. If the sets dont align up properly, then this will not work. Trying to Test the same

DataSet firstDsData = new DataSet();
DataSet secondDsData = new DataSet();
DataSet finalDsData = new DataSet();
DataSet DifferenceDataSet = new DataSet();
finalDsData.Merge(firstDsData);
finalDsData.AcceptChanges();
finalDsData.Merge(secondDsData);
DifferenceDataSet = finalDsData.GetChanges();
于 2016-09-13T11:08:22.497 回答
1

尝试这个

DataTable dtmismatch = Table1.AsEnumerable().Except(Table2.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>();
于 2015-08-27T10:33:59.700 回答
0

尝试以下方法:

初始化:

var columnId = new DataColumn("ID", typeof (int));
var columnName = new DataColumn("Name", typeof (string));
var table1 = new DataTable();
table1.Columns.AddRange(new[] {columnId, columnName});
table1.PrimaryKey = new[] {columnId};
table1.Rows.Add(1, "A");
table1.Rows.Add(2, "B");
table1.Rows.Add(3, "C");

var table2 = table1.Clone();
table2.Rows.Add(1, "A");
table2.Rows.Add(2, "B");
table2.Rows.Add(4, "D");

解决方案:

var table3 = table1.Copy();
table3.AcceptChanges();
table3.Merge(table2);

var distinctRows = from row in table3.AsEnumerable()
                   where row.RowState != DataRowState.Modified
                   select row;

var distintTable = distinctRows.CopyToDataTable();

当 table2 中存在 table1 中不存在的新行时,上述解决方案也适用。

distintTable包含CD

于 2013-02-21T13:10:48.627 回答
0

试试下面,这是非常基本的。将两组合并在一起,并获得差异。如果集合没有正确对齐,那么这将不起作用。

DataSet firstDsData = new DataSet();
DataSet secondDsData = new DataSet();
DataSet finalDsData = new DataSet();
DataSet DifferenceDataSet = new DataSet();
finalDsData.Merge(firstDsData);
finalDsData.AcceptChanges();
finalDsData.Merge(secondDsData);
DifferenceDataSet = finalDsData.GetChanges();
于 2014-08-13T12:25:06.223 回答
-1
Try This ...

    public DataTable getDiffRecords(DataTable dtDataOne, DataTable dtDataTwo)
    {
        DataTable returnTable = new DataTable("returnTable");

        using (DataSet ds = new DataSet())
        {
            ds.Tables.AddRange(new DataTable[] { dtDataOne.Copy(), dtDataTwo.Copy() });

            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];
            }

            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);

            for (int i = 0; i < dtDataOne.Columns.Count; i++)
            {
                returnTable.Columns.Add(dtDataOne.Columns[i].ColumnName, dtDataOne.Columns[i].DataType);
            }

            returnTable.BeginLoadData();
            foreach (DataRow parentrow in ds.Tables[0].Rows)
            {
                DataRow[] childrows = parentrow.GetChildRows(r1);
                if (childrows == null || childrows.Length == 0)
                    returnTable.LoadDataRow(parentrow.ItemArray, true);
            }

            foreach (DataRow parentrow in ds.Tables[1].Rows)
            {
                DataRow[] childrows = parentrow.GetChildRows(r2);
                if (childrows == null || childrows.Length == 0)
                    returnTable.LoadDataRow(parentrow.ItemArray, true);
            }
            returnTable.EndLoadData();
        }
        return returnTable;
    }
于 2018-12-21T09:06:32.983 回答