DataAdapter.update如果处理自动增长列的数据

DataAdapter.update可以很方便让我们更新dataset或datatable等的数据。 但是如果我们的数据库表里面如果有自动增长列时,如果在新增时,是数据库自动维护该列。那我们该如何处理这种列呢。

首先,我们知道在一张表里面只允许存在一个自动增长列的。而且数据库里面有个函数SCOPE_IDENTITY()取得自动增长的值的。(@@identity 是全局的。)。所以我们只要能在INSERT的时候能够取出这个值就可以。

那现在的问题就是如何在DataAdapter.Update的方法在INSERT中取值的问题。

我的做法是在SqlDataAdapter 增加RowUpdating  和RowUpdated事件,SqlDataAdapter sda = new SqlDataAdapter();
            SqlCommand cmdSelect = new SqlCommand("SELECT * FROM ZENGBin", _conn);
            SqlCommandBuilder _scb = new SqlCommandBuilder(sda);
            sda.SelectCommand = cmdSelect;
            sda.DeleteCommand = _scb.GetDeleteCommand();
            sda.InsertCommand = _scb.GetInsertCommand();
            sda.UpdateCommand = _scb.GetUpdateCommand();
            SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(sda);
            sda.RowUpdating += new SqlRowUpdatingEventHandler(sda_RowUpdating);
            sda.RowUpdated += new SqlRowUpdatedEventHandler(sda_RowUpdated);
            sda.Update(ds, "ZENGBin");

然后在RowUpdating 中如果发现改行是INSERT时,同时该行所在的表里面有自动增长列时,在command的commandText中加入一个变量@ID去取SCOPE_IDENTITY()的值。同时设置@ID是ParameterDirection.Output类型

 void sda_RowUpdating(object sender, SqlRowUpdatingEventArgs e)
        {

 if (e.StatementType == StatementType.Insert)
                    {
                        DataColumnCollection _columns = e.Row.Table.Columns;
                        foreach (DataColumn dc in _columns)
                        {
                            if (dc.AutoIncrement)
                            {
                                e.Command.CommandText = e.Command.CommandText + ";SELECT @ID = SCOPE_IDENTITY()";
                                e.Command.Parameters.Add("@ID", SqlDbType.Int);
                                e.Command.Parameters["@ID"].Direction = ParameterDirection.Output;
                                //dc.ReadOnly = false;
                                //e.Row[dc] = e.Command.Parameters["@ID"].Value;
                                //dc.ReadOnly = true;
                                break;
                            }
                        }                       
                    }

}

然后在RowUpdated的时候取出值,回写到行里面。注意一下因为如果是自动增长列的只读的,所以在更新回值的时候,先要去掉只读。

 void sda_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
        {
            if (e.StatementType == StatementType.Insert && e.Row != null)
            {
                DataColumnCollection _columns = e.Row.Table.Columns;
                foreach (DataColumn dc in _columns)
                {
                    if (dc.AutoIncrement)
                    {
                        dc.ReadOnly = false;
                        e.Row[dc] = e.Command.Parameters["@ID"].Value;
                        dc.ReadOnly = true;
                        break;
                    }
                }   
            }
        }

还有点注意下,如果@ID有可能在表的列中存在了。如果需要判断是否存在,如果存在就要取另外一个名字哦。 呵呵。

这是我的做法,不知道还有没有别的方法。有的话,请赐教。

 

 

posted @ 2010-01-06 10:42  Zengbin  阅读(1439)  评论(1编辑  收藏  举报