DataSet Merge 和 AcceptChanges 得到 DiffGram [英] DataSet Merge and AcceptChanges to get DiffGram

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

问题描述

我有两个 XML 数据集,ds1 和 ds2.我使用 .ReadXML(name, 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):

当将新的源 DataSet 合并到目标,任何带有未更改的 DataRowState 值,修改或删除匹配到具有相同主键的目标行值.带有 a 的源行已添加的 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.

因此,对于每个 DataTable,您应该设置 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);

关于您的评论,您可以通过下面的代码传递表格来拒绝合并行的更改,这些更改并未真正更改.接受 DataTable 的方法会更整洁.在调用 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().

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

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