数据集合和AcceptChanges的得到的DiffGram [英] DataSet Merge and AcceptChanges to get DiffGram

查看:142
本文介绍了数据集合和AcceptChanges的得到的DiffGram的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个XML数据集,DS1和DS2。我读了这些数据集与.ReadXML(姓名,XmlReadMode.ReadSchema)。我试图通过使用一个合并的数据组以获得与两个之间的区别一个DiffGram如下所示。

I have two XML data sets, ds1 and ds2. I read these data sets with .ReadXML(name, XmlReadMode.ReadSchema). I am trying to get a DiffGram with the differences between the two by using a merged data set as shown below.

DataSet ds3 = new DataSet();
ds3.Merge(ds1);
ds3.AcceptChanges();
ds3.Merge(ds2);

DataSet ds4 = ds3.GetChanges();

ds4.WriteXml("ds4.xml", XmlWriteMode.DiffGram);

DS1和DS2每个包含多个元素。我通过复制DS1文件和修改的记录之一创建DS2。

ds1 and ds2 each contains multiple elements. I created ds2 by copying the ds1 file and modifying one of the records.

然而,当我在看执行后ds4.xml,它显示了所有的记录集DS1和所有的记录DS2(所以它显示重复的条目),以及DS2的更新被列为... diffgr :hasChanges =插入>。看来,这只是插入,不更新现有记录。

However, when I look at ds4.xml after execution, it shows all of the record sets in ds1 and all of the records in ds2 (so it shows duplicate entries), and the ds2 updates are listed as ...diffgr:hasChanges="inserted">. It seems that this is only inserting, not updating existing records.

我怎样才能得到DS4,只显示是在DS2的变化?

How can I get ds4 to only show the change that was made in ds2?

推荐答案

插入与更新一般的这种现象的发生是由于缺乏定义的主键。你有没有在表上设置主键?这列是如何在合并过程中匹配了。 每MSDN (重点煤矿):

This behavior of inserting versus updating typically occurs due to the lack of defined primary keys. Have you set primary keys on the tables? That's how the columns are matched up during a merge. Per MSDN (emphasis mine):

在合并了新的源数据进   目标,与任何源行   不变DataRowState价值,   修改或删除的匹配   具有相同主键的目标行   值。与源行   新增的DataRowState值   匹配与新的目标行   相同的主键值作为新   源行。

When merging a new source DataSet into the target, any source rows with a DataRowState value of Unchanged, Modified, or Deleted are matched to target rows with the same primary key values. Source rows with a DataRowState value of Added are matched to new target rows with the same primary key values as the new source rows.

因此​​,对于每个数据表你应该设置的 的PrimaryKey 属性。我几年前写了MSDN的这个详细的例子 DataTable.Merge 页。你可以看看这里写下:的合并使用主键的预期结果

Therefore, for each DataTable you should set the PrimaryKey property. I wrote a detailed example of this on the MSDN DataTable.Merge page a few years ago. You can take a look at that write up here: Merge using Primary Keys for Expected Results.

这种方法的一个简单的例子:

A brief example of this approach:

DataTable dt1 = new DataTable();
dt1.Columns.Add("ID", typeof(int));
dt1.Columns.Add("Customer", typeof(string));
dt1.PrimaryKey = new[] { dt1.Columns["ID"] };
dt1.Rows.Add(new object[] { 1, "Ahmad" });

DataTable dt2 = new DataTable();
dt2.Columns.Add("ID", typeof(int));
dt2.Columns.Add("Customer", typeof(string));
dt2.PrimaryKey = new[] { dt2.Columns["ID"] };
dt2.Rows.Add(new object[] { 1, "Mageed" });

// try without primary keys and it'll add a new record
dt1.Merge(dt2);

编辑:关于你的评论,你可以拒绝并没有真正通过将表通过下面的code改变对合并后的行更改。接受一个数据表的方法将整洁。重要的是,这个code用于调用的 DataTable.AcceptChanges()方法,否则行状态将被丢弃。

regarding your comment, you could reject the changes on merged rows that were not really changed by passing the table through the code below. A method that accepts a DataTable would be neater. It's important that this code is used prior to calling the DataTable.AcceptChanges() method, otherwise the row states will be discarded.

使用LINQ:

foreach (DataRow row in dt1.Rows)
{
    if (row.RowState == DataRowState.Modified)
    {
        var original = dt1.Columns.Cast<DataColumn>()
                          .Select(c => row[c, DataRowVersion.Original]);

        bool isUnchanged = row.ItemArray.SequenceEqual(original);
        if (isUnchanged)
        {
            row.RejectChanges();
        }
    }
}

如果LINQ是不是一种选择:

If LINQ isn't an option:

foreach (DataRow row in dt1.Rows)
{
    if (row.RowState == DataRowState.Modified)
    {
        bool isUnchanged = true;
        foreach (DataColumn col in dt1.Columns)
        {
            if (!row[col.ColumnName].Equals(row[col.ColumnName, DataRowVersion.Original]))
            {
                isUnchanged = false;
                break;
            }
        }

        if (isUnchanged)
        {
            row.RejectChanges();
        }
    }
}

您可以致电 dt1.AcceptChanges()之后做到这一点。

You can call dt1.AcceptChanges() after this is done.

这篇关于数据集合和AcceptChanges的得到的DiffGram的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆