zoukankan      html  css  js  c++  java
  • AcceptChanges()和RejectChanges()原理

    今天我遇到一个题目,是关于AcceptChanges()和RejectChanges()方法的,考虑到可能很多人不清楚这些概念。
    所以拿出来讲讲。由这个问题我们也深入了解一下这两个方法。
    为了不在显示略文时显示出代码来,我就在刚开始多打一点字了。呵。。。

    题目的代码如下:

    protected void Button1_Click(object sender, EventArgs e)
        {
            DataSet ds= new DataSet();
     
                 DataTable tb = ds.Tables.Add("Items");
                 DataColumn pk = tb.Columns.Add("ID", typeof(Int32));
                 tb.Columns.Add("Items", typeof(string));
                 tb.PrimaryKey = new DataColumn[] {pk};
     
                for(int i=0;i<6;i++)
                {
                    DataRow dr = tb.NewRow();
                    dr[0] = i.ToString();
                    dr[1] = "Itme "+i;
                    tb.Rows.Add(dr);
                }

                tb.Rows[0].Delete();
                tb.Rows.RemoveAt(1);
                tb.Rows.RemoveAt(2);
                tb.RejectChanges();

                GridView1.DataSource = tb;
                GridView1.DataBind();

        }

    我们看到在第3-16行,实际上我们是生成了一个DataTable,这个dt有两个字段,分别是ID和Items,然后通过添加6条记录。
    如果到此为止,那么这个的内容应该是如下:

    ID Items
    0 Item 0
    1 Item 1
    2 Item 2
    3 Item 3
    4 Item 4
    5 Item 5

    不过我们在第19,20,21行中分别删除了第0行,然后是移除第1行,移除第2行。当然如果只是这样就算不上题目了,我们在18和22行用到了DataTable的AcceptChanges()方法和RejectChanages()方法。

    首先大家先想一下答案是什么?随便我把MSDN上对这两个方法的解释粘一下,好让大家理解。

    DataTable.AcceptChanges方法
    提交自上次调用 AcceptChanges 以来对该表进行的所有更改。调用 AcceptChanges 时,任何仍处于编辑模式的 DataRow 对象将成功结束其编辑。DataRowState 也会随之更改:所有状态为 Added 和 Modified 的行的状态都变为 Unchanged;状态为 Deleted 的行则被移除。
    在您尝试使用 DbDataAdapter.Update 方法更新 DataSet 之后,通常会对 DataTable 调用 AcceptChanges 方法。

    DataTable.RejectChanges方法
    回滚自该表加载以来或上次调用 AcceptChanges 以来对该表进行的所有更改。
    调用 RejectChanges 时,任何仍处于编辑模式的 DataRow 对象将取消其编辑。新行被移除。DataRowState 设置为 Modified 或 Deleted 的行返回到其初始状态。

    一个意思表示立即更新,一个表示在接受上次调用AcceptChanges后进行回滚。

    好的,那么是不是说,我们这儿的3条记录都能够回滚回来呢?

    我们先公布一下答案吧,看看和大家想的是不是一样的。

    ID Items
    0 Item 0
    2 Item 2
    4 Item 4
    5 Item 5


    OK,答案表明并不是所有的记录都被回滚回来了,似乎只有0被回滚了。这并不是奇怪,那是因为我们使用删除行的方法不一样,一个是Delete(),一个是RemoveAt(int)。

    我们通过在MSDN中的查询了解到在使用 Delete 方法后,RowState 变成“已删除”。在您调用 AcceptChanges 之前,它一直保持“已删除”。可通过调用 RejectChanges 取消删除行。

    而RemoveAt表示当移除行时,该行中的所有数据都将丢失。您还可以调用 DataRow 类的 Delete 方法来标记某行以供移除。调用 RemoveAt 等同于先调用 Delete 再调用 AcceptChanges。

    那就是说,我们使用Delete()方法删除行后是可以回滚的,而使用RemoveAt(int)方法是不能回滚的。
    所以刚刚前面我们删除的三行,只回滚了0的那行是完成正确的。我想大家对答案应该没有疑问了。

    从这个题目中,我引申出几个题目来,看看大家会不会做哦?

    下面接着,我们再来修改一下代码看看。

    tb.Rows[0].Delete();
    tb.AcceptChanges();
    tb.Rows.RemoveAt(
    1);
    tb.Rows.RemoveAt(
    2);
    tb.RejectChanges();


    我们把AcceptChanges()方法放到后Delete()后面,很明显这样做,会让ID为0的数据也无法回滚。为什么大家看我上面粘的MSDN解释就知道了。

    那么就这的话,答案会是什么呢,会不会有人想到是2,4,5呢。

    想到2,4,5的人就错了哦。因为当接受AcceptChanges()方法后,前面的0行就彻底删除了,这时数据应该是1,2,3,4,5,然后RemoveAt(1)表示删除第2行,删除后也是立刻删除的,无法回滚,所以这时数据应该是1,3,4,5,接着RemoveAt(2)删除第3行,所以答案应该是1,3,5。
    而原来把AcceptChanage()方法放在Delete()前面时,当调用tb.Rows[0].Delete()时,只是标记状态为删除,并没有直接移除第0行,所以那个RemoveAt(1),还是从0,1,2,3,4,5中删除第2行,所以答案是0,2,4,5。

    好,我们再修改一下代码:

    tb.AcceptChanges();
    tb.Rows[
    0].Delete();            
    tb.Rows.RemoveAt(
    1);
    tb.AcceptChanges();
    tb.Rows.RemoveAt(
    2);
    tb.RejectChanges();

    大家来猜猜答案是什么呢?

    不知道有没有人想到会是2,4,5,实际上不对。
    正确的答案应该是2,3,5。

    首先的第一个AcceptChanages表示将无法回滚前面添加数据的操作。接着第二个AcceptChanages表示彻底删除Delete()所删除的数据,这个时候数据就只剩下2,3,4,5了,然后再RemoveAt(2)把第三行删除了,所以就剩下2,3,5了。

    好的,我们再把第一个AcceptChanages()方法给删除了,大家想想答案会是什么呢,代码如下:

    tb.Rows[0].Delete();            
    tb.Rows.RemoveAt(
    1);
    tb.AcceptChanges();
    tb.Rows.RemoveAt(
    2);
    tb.RejectChanges();

    可能有人说了,AcceptChanages()方法是对前面的语句生效的,所以你把这个删除了一点问题也没有,答案当然还是2,3,5了,其实这种说法是错误的。

    这段代码的正确答案是1,3,5。
    为什么会是这样呢,那是因为当Delete()方法在前面没有接收到AcceptChaages()方法后,会彻底删除因为没有必要回滚。所以RemoveAt(1)在执行时,实际上数据是1,2,3,4,5,它删除第2行,也就是3。

    好的,我们再看看下面的这段代码:

    tb.Rows[0].Delete();            
    tb.Rows.RemoveAt(
    1);
    tb.Rows.RemoveAt(
    2);
    tb.AcceptChanges();
    tb.RejectChanges();


    不知道有没有人会笑话我,实际上这段代码和上面的代码是一个效果哦。

    那么我们再看看这段代码呢?

    tb.Rows[0].Delete();            
    tb.Rows.RemoveAt(
    1);
    tb.Rows.RemoveAt(
    2);
    tb.RejectChanges();


    我们把所有的AcceptChanges()方法都给去掉了,那么只剩下RejectChanages()方法了,会是什么样的结果呢?
    结果返回空记录了,为什么呢????

    其实在前面最早是无已经给出定义了,不知道的同学是太粗心了哦。自己去看哦。

  • 相关阅读:
    POJ 3630 Phone List/POJ 1056 【字典树】
    HDU 1074 Doing Homework【状态压缩DP】
    POJ 1077 Eight【八数码问题】
    状态压缩 POJ 1185 炮兵阵地【状态压缩DP】
    POJ 1806 Manhattan 2025
    POJ 3667 Hotel【经典的线段树】
    状态压缩 POJ 3254 Corn Fields【dp 状态压缩】
    ZOJ 3468 Dice War【PD求概率】
    POJ 2479 Maximum sum【求两个不重叠的连续子串的最大和】
    POJ 3735 Training little cats【矩阵的快速求幂】
  • 原文地址:https://www.cnblogs.com/wangchao928/p/2637273.html
Copyright © 2011-2022 走看看