ADO.Net笔记

对ADO.net 数据存取的一些测试心得:

1. 使用控件如GridControl GridView的DataSource创建DataSet与手动创建的DataSet效果是相同的,在项目中应使用强类型的DataSet

2.更新数据时,需指定4种SqlCommand,InsertCommand、DeleteCommand、UpdateCommand、SelectCommand 还可以使用SqlCommandBuilder为SqlDataAdapter自动生成4个SqlCommand。
使用方法: 在创建SqlCommandBuilder时将SqlDataAdapter传入即可,即 SqlCommandBuilder scb = new SqlCommandBuilder(da);

3.当手工为DataAdapter指定InsertCommand:

string strSql = "Insert into Employees(LastName,FirstName,Title,TitleOfCourtesy,Address,City,Region) " +
                           "Values(@LastName,@FirstName,@Title,@TitleOfCourtesy,@Address,@City,@Region)" +
                           "Select 222 as EmployeeID,LastName,FirstName,Title,TitleOfCourtesy,Address,City,Region "+
                           " from Employees Where LastName = @LastName and FirstName = @FirstName";
           da.InsertCommand = new SqlCommand(strSql, conn);
           da.InsertCommand.Parameters.Add("@LastName", SqlDbType.NChar,20,"LastName");
           da.InsertCommand.Parameters.Add("@FirstName", SqlDbType.NChar, 20, "FirstName");
           da.InsertCommand.Parameters.Add("@Title", SqlDbType.NChar, 20, "Title");
           da.InsertCommand.Parameters.Add("@TitleOfCourtesy", SqlDbType.NChar, 20, "TitleOfCourtesy");
           da.InsertCommand.Parameters.Add("@Address", SqlDbType.NChar, 20, "Address");
           da.InsertCommand.Parameters.Add("@City", SqlDbType.NChar, 20, "City");
           da.InsertCommand.Parameters.Add("@Region", SqlDbType.NChar, 20, "Region");
           da.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;

此处有需要注意: 1. InsertCommand.UpdatedRowSource 属性有4个 分别是:Both、FirstReturnedRecord、None、OutputParameters. Both是既用每一行记录也使用传出的参数刷新table

    1. 注意在insertCommand中还有一条Select的语句,用来刷新DataSet中的表在更新后的数据。而且这条Select所返回的记录需要在
        • DataAdapter.RowUpdated事件中的参数取得。
        • RowUpdated事件,此事件会根据每行记录而触发。
            • void da_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
                      {
                          
                          if (e.StatementType == StatementType.Insert && e.Status == UpdateStatus.Continue)
                          {
                              string sql = "select @EmployeeID = @@IDENTITY";
                              SqlCommand cmdRefresh = new SqlCommand(sql,e.Command.Connection);
                              SqlParameter p = cmdRefresh.Parameters.Add("@EmployeeID", SqlDbType.Int);
                              p.Direction = ParameterDirection.Output;
                              cmdRefresh.ExecuteNonQuery();
                              e.Row["EmployeeID"] = cmdRefresh.Parameters["@EmployeeID"].Value;
                              //gridView1.RefreshRow();
                              //northwindDataSet.Employees.Rows[gridView1.FocusedRowHandle]["EmployeeID"] = cmdRefresh.Parameters["@EmployeeID"].Value;
                          }
                      }
              另外,由于OrderId是自增列,如果要刷新此列,需要用@@IDENTITY 或SCOPE_IDENTITY()获得。
              这个事件中,把由InsertCommand的select语句传来的记录指给e.Row中指定列,就完成了前台记录刷新。
               
              4. 再看一代码,用来保存数据的
               
              private void button1_Click(object sender, EventArgs e)
                     {
                         if (northwindDataSet.HasChanges(DataRowState.Added) || northwindDataSet.HasChanges(DataRowState.Modified))
                         {
                             NorthwindDataSet.EmployeesDataTable dtUpdate = northwindDataSet.Employees.GetChanges(DataRowState.Added) as NorthwindDataSet.EmployeesDataTable;
                             
                             if (dtUpdate != null)
                                 da.Update(northwindDataSet.Employees.Select("","",DataViewRowState.Added));
                             dtUpdate = northwindDataSet.Employees.GetChanges(DataRowState.Modified) as NorthwindDataSet.EmployeesDataTable;
                             if (dtUpdate != null)
                                 da.Update(dtUpdate);
                             northwindDataSet.Employees.AcceptChanges();
                             //MessageBox.Show(northwindDataSet.Employees.Rows[gridView1.FocusedRowHandle]["FirstName"].ToString());
                         }
                     }
              
              此处也要注意,先前使用了dtUpdate传给da.update()结果导致RowUpdated方法中刷新记录失效,因为这里将GridView所绑定的表
        的记录筛选了一份放在dtUpdate之中,从而导致RowUpdated方法将dtUpdate的记录刷新。所以在此处,我将 da.Update(dtUpdate)换成了 da.Update(northwindDataSet.Employees.Select(…)) 成功刷新记录。

              每次更新完成之后,应调用一次 northwindDataSet.Employees.AcceptChanges(); 将Dataset中的每一行状态恢复。
              还要注意的是,如果使用DataAdapter.Update删除操作时,需要看看EmployeeID有没有刷新,如果此主键未刷新那么将导致删除失败。 这是因为,Delete时候需要靠此主键做为WHere条件.

                使用WebService更新数据,那么可以用.Employees.GetChanges(DataRowState.Modified) 将表中挂起的记录取出再传回WebService,这样可以减少网络数据量.  而经过更新的记录可以用DataSet.Merge方法合并.再显示到前台界面上.
                关于DataSet.Merge暂未测试。


    strSQL = "UPDATE OrderDetailsWithTimestamp " +
                             "  SET OrderID = @OrderID_New, ProductID = @ProductID_New, " +
                             "      Quantity = @Quantity_New, UnitPrice = @UnitPrice_New " +
                             "  WHERE OrderID = @OrderID_Old AND ProductID = @ProductID_Old " +
                             "    AND TimestampColumn = @TimestampColumn_Old";
                    da.UpdateCommand = new SqlCommand(strSQL, cn);
                    da.UpdateCommand.Parameters.Add("@OrderID_New", SqlDbType.Int, 0, "OrderID");
                    da.UpdateCommand.Parameters.Add("@ProductID_New", SqlDbType.Int, 0, "ProductID");
                    da.UpdateCommand.Parameters.Add("@Quantity_New", SqlDbType.SmallInt, 0, "Quantity");
                    da.UpdateCommand.Parameters.Add("@UnitPrice_New", SqlDbType.Money, 0, "UnitPrice");
                    da.UpdateCommand.Parameters.Add("@OrderID_Old", SqlDbType.Int, 0, "OrderID").SourceVersion = DataRowVersion.Original;
                    da.UpdateCommand.Parameters.Add("@ProductID_Old", SqlDbType.Int, 0, "ProductID").SourceVersion = DataRowVersion.Original;
                    da.UpdateCommand.Parameters.Add("@TimestampColumn_Old", SqlDbType.Timestamp, 8, "TimestampColumn").SourceVersion = DataRowVersion.Original;
                    da.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
    
    

     

     

    static void HandleRowUpdated_RefreshAfterUpdate(object sender, SqlRowUpdatedEventArgs e)
            {
                if (e.Status == UpdateStatus.Continue &&
                    (e.StatementType == StatementType.Insert || e.StatementType == StatementType.Update))
                {
                    string strSQL;
                    strSQL = "SELECT @Quantity = Quantity, @UnitPrice = UnitPrice, " +
                             "       @TimestampColumn = TimestampColumn FROM OrderDetailsWithTimestamp " +
                             "  WHERE OrderID = @OrderID AND ProductID = @ProductID";
                    SqlCommand cmd = new SqlCommand(strSQL, e.Command.Connection);
                    cmd.Parameters.Add("@Quantity", SqlDbType.SmallInt).Direction = ParameterDirection.Output;
                    cmd.Parameters.Add("@UnitPrice", SqlDbType.Money).Direction = ParameterDirection.Output;
                    cmd.Parameters.Add("@TimestampColumn", SqlDbType.Timestamp).Direction = ParameterDirection.Output;
    
                    cmd.Parameters.AddWithValue("@OrderID", e.Row["OrderID"]);
                    cmd.Parameters.AddWithValue("@ProductID", e.Row["ProductID"]);
    
                    cmd.ExecuteNonQuery();
                    e.Row["Quantity"] = cmd.Parameters["@Quantity"].Value;
                    e.Row["UnitPrice"] = cmd.Parameters["@UnitPrice"].Value;
                    e.Row["TimestampColumn"] = cmd.Parameters["@TimestampColumn"].Value;
                }
    
    posted @ 2012-11-18 21:48  perock  阅读(258)  评论(0编辑  收藏  举报