none
DataTable的Merge方法合并问题 RRS feed

  • 问题

  • 由于我在数据库中所建的主键列为自增列,因此,保存DataTable到数据库中后才可以获取这个键值。此时如果不反过来更新DataTable,当再次保存时就会引发并发冲突。这一点显而易见。

    然而无意中发现,我用DataTable的Merge方法合并重新获取的表,居然可以更新那一行,也就是说,原本DataTable里面主键被赋予“-1”的临时键居然可以与重新获取的表的实际自增取得的键值视同相同。这是为什么呢?难道该数据行有个隐藏的行关键字?

    另外,对于这种数据库表为自增列的,是不是必须要重新获取数据已达到数据一致的目的,还有其他办法吗?

    谢谢高手作答。


    陈锦巍

    2014年6月24日 15:34

全部回复

  • Hello,

    >>由于我在数据库中所建的主键列为自增列,因此,保存DataTable到数据库中后才可以获取这个键值。此时如果不反过来更新DataTable,当再次保存时就会引发并发冲突。这一点显而易见。

    楼主可以展示下你的代码吗,因为按照你的描述,主键为自增列的话,再次保存datatable到数据库,主键应该会自增的,不会产生冲突。下面是个两次连续保存DataTable到数据库的代码:

    SqlConnection connection = new SqlConnection(connectionString);
    
    
                try
    
                {
    
                    if (connection.State == ConnectionState.Closed)
    
                    {
    
                        connection.Open();
    
                    }
    
    
                    DataTable dtProject = new DataTable("Project");
    
    
                    SqlCommand cmd = new SqlCommand("select * from [Project]", connection);
    
    
                    SqlDataAdapter da = new SqlDataAdapter(cmd);
    
    
                    SqlCommandBuilder db = new SqlCommandBuilder(da);
    
    
                    da.Fill(dtProject);
    
    
                    DataRow newrow = dtProject.NewRow();
    
    
                    newrow["ProjectName"] = "1";
    
    
                    dtProject.Rows.Add(newrow);
    
    
                    da.Update(dtProject);
    
    
                    da.Update(dtProject);
    
                }
    
                catch (Exception)
    
                {
    
    
                    throw;
    
                }
    
                finally
    
                {
    
                    connection.Close();
    
                }
    

    >>然而无意中发现,我用DataTableMerge方法合并重新获取的表,居然可以更新那一行,也就是说,原本DataTable里面主键被赋予“-1”的临时键居然可以与重新获取的表的实际自增取得的键值视同相同。这是为什么呢?难道该数据行有个隐藏的行关键字?

    楼主你是怎么merge,可以展示下代码吗?我按照你的描述合并重现回获取的表 他只会在原来的datatable上追加列而已,所以感到很疑惑。

    >>另外,对于这种数据库表为自增列的,是不是必须要重新获取数据已达到数据一致的目的,还有其他办法吗?

    就我知道的,目前只是这样的。如果楼主找到新的方法,可以分享出来。

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年6月25日 6:44
    版主
  • 哦不好意思我没说清楚,主键自增,是在sql server里产生的,所以datatable新增一行时这个列会是 -1 -2之类的待定值,这就需要更新到数据库后还要取一次值以保持一致。但发现,取值后用merge照样可以正确合并的。为什么呢?

    代码错综,有点不好贴出。我是分了三层做的,本来写入数据库后,是应该重新取值的,然而,出于另外的想法,尝试了merge新取得的表,结果居然能良好的实现,并没有那种重复的行。但是看merge的说明,可是说主键要一致才可以合并。而这种自动生成的主键,确可以与数据库中实际产生的主键那一行完美合并。

    代码:

     public bool SaveBill()
             {
                 var Dt = this.billData.GetChanges();
                 if (Dt!=null && DataSetOper.SaveDataSet(Dt))
                 {
    
                //本来保存完数据就可以返回true的,但因为明细项没有用表单+行号作为联合主键,而是在sqlserver中新建一主键列,设为自增,步长为1,这样需要数据写到数据库中才能产生这一列的正确数值。
    
               //这样就需要重新读取数据,下面是我用merge方法合并新取得的数据到原来的明细表。结果很正常的合并了。
    
                    var dt = GetData();
                     billData.Relations[0].ChildTable.Merge(dt.Relations[0].ChildTable);
       
                     return true;
                 }
                 return false;
             }
    

    不知为什么呢?


    陈锦巍



    2014年6月26日 12:18
  • >> billData.Relations[0].ChildTable.Merge(dt.Relations[0].ChildTable);

    merge前楼主有check billData.Relations[0].ChildTable里有数据吗?


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年6月30日 6:35
    版主
  • 有数据的,而且数据的自增列的值是临时值(-1,-2等),就是因为这样,发现居然重新从数据库读出的数据居然可以与他合并呢,不是说主键必须一致吗?现在发现新值的居然可以合并到原来临时值(不知内部是不是还有什么隐藏关键字才使得这种情况可以出现)。

    陈锦巍

    2014年7月9日 9:15
  • 这么奇怪,按照楼主的代码我看到的自增列的值都是空,楼主用什么环境,我的是Framework4.5

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年7月11日 3:27
    版主
  • 我用的是4.0,一开始新增一行时由于是自增列,datatable给出了临时值-1,再增一行就会是-2,然后,我将数据保存到数据库,这时写入数据库之后该主键才会根据表内主键的最大值而产生其实机值。此时需要重新读取数据库中的此表到DataTable,否则再次保存时就会引发冲突。然而我恰恰用merge方法合并新获得的数据。如果照原则来说,那主建为-1 -2的行是还会存在的,DataTable里面是会多出了行。可是实际我却看到他居然会认识到原来的-1 -2的那些行与取回的数据行是同一行。居然给合并了。呵呵,这倒也是正是我想要的。只是看合并规则,这点倒不附和了呢。是不是合并规则里面并没有包括这种自增列临时主键值的情况?是不是这种情况他会比较其他的列是否一致,一致就自然可以合并了。因为此时再取回的数据也只有这个自增列值不一样,其他烈都相同。而原来DataTable中的只是临时值,我想临时值可能没有参与比较吧。

    陈锦巍

    2014年7月12日 12:45