WEB开发网
开发学院数据库MSSQL Server 从Pocket Access向SQL Server CE进行数据库迁移 阅读

从Pocket Access向SQL Server CE进行数据库迁移

 2007-12-27 15:32:28 来源:WEB开发网   
核心提示:Mobile Sales .NET 示例Mobile Sales .NET 示例演示了如何将用 eMbedded Visual Basic 编写并且使用 ADO CE 访问 Pocket Access 数据库中的数据的应用程序迁移到 .NET Compact Framework,以便它使用 ADO.NET 访问 SQL

Mobile Sales .NET 示例

Mobile Sales .NET 示例演示了如何将用 eMbedded Visual Basic 编写并且使用 ADO CE 访问 Pocket Access 数据库中的数据的应用程序迁移到 .NET Compact Framework,以便它使用 ADO.NET 访问 SQL Server CE 数据库中的数据。该示例随附在 Larry Roof 于 2001 年撰写的文章 Data To Go 中。

Mobile Sales .NET 示例是用 Visual Studio.NET2003 创建的。它由单个窗体组成,如图 2 所示。

图 2. Mobile Sales .NET

其方案是一个访问很多个客户的送货司机。在每个站点,他都会取走一份定单。对于每份定单,他都会选择产品,输入数量,然后点击 Add。如果该司机出了错,则他会选择项行,然后点击 Delete。要保存定单,该司机可以点击 Save this order 菜单命令;然后,他可以接着处理下一份定单。当该司机保存了所有客户定单时,他退出应用程序。该示例的工作方式与原始的 eMbedded Visual Basic 示例 (Data To Go) 相同。

代码演练

当应用程序启动时,它运行以下代码。在原始 eVB 示例中,这些代码位于窗体的 Load 事件中。

Dim cnMobileSalesAs ADOCE.Connection
Private Sub Form_Load()
' Set up an error handler.
' NOTE: eMbedded Visual Basicsupports only the On Error Resume
' Next method.
 On Error Resume Next
 Err.Clear
' Build the menu bar.
 ConstructMenuBar
' Make a connection to the database.
 Set cnMobileSales= CreateObject("ADOCE.Connection.3.0")
 cnMobileSales.Open "data source=" & App.Path & "Mobile Sales.cdb"
' Was the connection successful?
 If cnMobileSales.Errors.Count > 0 Then
   MsgBox "Error connecting to database." & vbCrLf & _
           "Error " & Err.Number & vbCrLf & _
           Err.Description, _
           vbCritical, "Open Database"
   Set cnMobileSales= Nothing
   On Error GoTo 0
   App.End
 End If
' Load the customer and product information.
 LoadComboBox cmbCustomers, "Customers", "CustomerID", _
       "CustomerName", True
 LoadComboBox cmbProducts, "Products", "ProductID", _
       "Description", False
' Set up the selected product's list view control.
 FormatListView
End Sub

如上述代码的第一行所示,连接 (cnMobileSales) 被声明为类型 ADOCE.Connection 的窗体变量。应用程序创建了一个 ADO CE Connection 对象并且打开了 (Open) 该对象。连接字符串的数据源设置为与应用程序位于同一目录中的 Pocket Access 数据库文件。然后,应用程序检查在试图打开数据库的过程中是否发生了错误。如果发生了错误(在 Connection 对象上的 Errors 集合中枚举),则会在消息框中显示第一个错误,并且该应用程序将关闭。然后,两个方法调用 (LoadComboBox) 将数据加载到两个 ComboBox 控件中。

请注意,两个方法调用从属于窗体的设计:MenuBar 控件 (ConstructMenuBar) 的设计以及 ListView 控件 (FormatListView) 的设计。有关详细信息,请参阅原始的 eMbedded Visual Basic 示例代码。

在迁移之后,窗体的 Load 事件的 Visual Basic .NET 代码如下所示。

Private cn As SqlCeConnection
Private Sub MainForm_Load(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles MyBase.Load
 Try
   ' Make the connection to the database
   cn = New SqlCeConnection( _
     "Data Source=" + appPath + "MobileSales.sdf")
   cn.Open()
 Catch ex As SqlCeException
   MessageBox.Show(ex.Message, Me.Text)
   cn.Close()
   Me.Close()
 End Try
 ' Load the customer and product information.
 loadComboBox(customerComboBox, "Customers", "CustomerID", _
             "CustomerName", True)
 loadComboBox(productComboBox, "Products", "ProductID", _
             "Description", False)
End Sub

上述代码中的错误处理具有高度的结构性。如果在应用程序尝试连接到数据库的过程中发生了错误,则会引发异常,就像在 .NET Compact Framework 中处理任何其他错误一样。如果您需要有关该异常的详细信息,则可以分析该异常对象 (ex) 上的错误集合 (Errors)(有关详细信息,请参阅前面的“ADO CE to ADO.NET”部分)。上述代码的第一行将该集合 (cn) 声明为类型 System.Data.SqlServerCe.SqlCeConnection 的类成员变量。应用程序将连接字符串传递给 Connection 对象的构造函数;该构造函数还打开指向数据库的连接。请注意,MainMenu(添加菜单选项)控件和 ListView(添加列)控件的设计是在窗体设计器中进行的;而在以前的工具中,需要大量的代码。

在 C# 中,相同的代码如下所示。

private SqlCeConnectioncn;
private void MainForm_Load(object sender, System.EventArgs e)
{
 try
 {
   // Make the connection to the database
   cn = new SqlCeConnection(
     @"Data Source=" + appPath + @"MobileSales.sdf");
   cn.Open();
 }
 catch (SqlCeExceptionex)
 {
   MessageBox.Show(ex.Message, this.Text);
   cn.Close();
   this.Close();
 }
 // Load the customer and product information
 loadComboBox(customerComboBox, "Customers", "CustomerID",
   "CustomerName", true);
 loadComboBox(productComboBox, "Products", "ProductID",
   "Description", false);
}

在原始的 eMbedded Visual Basic 示例中,用于将数据加载到 ComboBox 控件中的代码如下所示。

Private Sub LoadComboBox(cmbObject As ComboBox, _
       ByVal strTableName As String, _
       ByVal strIDColumn As String, _
       ByVal strNameColumn As String, _
       ByVal bolSelect As Boolean)
       
 Dim rsTable As ADOCE.Recordset
 Dim strSQLAs String
' Set up error handling.
 On Error Resume Next
 Err.Clear
' Build a RecordSet of all the information.
 strSQL= "SELECT* FROM " & strTableName
 Set rsTable = CreateObject("ADOCE.Recordset.3.0")
 rsTable.Open strSQL, cnMobileSales, adOpenDynamic, _
           adLockOptimistic
 If (Err.Number) Then
   MsgBox "Error retreiving " & strTableName & _
           " information. ", vbCritical, "Fill ComboBox"
   On Error GoTo 0
   Exit Sub
 End If
' Place the information into the combo box.
 Do While Not (rsTable.EOF)
' Place name in combo box.
   cmbObject.AddItem rsTable(strNameColumn).Value
' Place the ID number into the itemdata element for the
' name that was just added.
   cmbObject.ItemData(cmbObject.NewIndex) = _
     CLng(rsTable(strIDColumn).Value)
' Attempt to move to the next record.
   rsTable.MoveNext
 Loop
' Select the first item in the list.
 If (cmbObject.ListCount > 0) And (bolSelect = True) Then
   cmbObject.ListIndex = 0
 End If
' Close the recordset.
 rsTable.Close
 Set rsTable = Nothing
 
 On Error GoTo 0
 
End Sub

在设置错误处理以后,应用程序将表 (strTableName) 中的所有行加载到 ADOCE.RecordSet (rsTable) 中。然后,应用程序遍历 RecordSet 中的行,并且对于每个行,应用程序都会在 ComboBox 控件 (cmbObject) 中插入一个项。所插入的每个项还都获得附加到 ItemData 属性的标识。

在迁移以后,相同的 Visual Basic .NET 代码如下所示。

Private Sub loadComboBox(ByVal comboBox As ComboBox, _
   ByVal tableName As String, ByVal valueColumnName As String, _
   ByVal displayColumnName As String, ByVal selectFirst As     Boolean)
 Try
   Dim sql As String = "SELECT" + valueColumnName + ", " + _
           displayColumnName + " FROM " + tableName + _
           " ORDER BY " + displayColumnName
   Dim da As New SqlCeDataAdapter(sql, cn)
   Dim ds As New DataSet
   da.Fill(ds, tableName)
   comboBox.DisplayMember = displayColumnName
   comboBox.ValueMember = valueColumnName
   comboBox.DataSource = ds.Tables(tableName)
 Catch ex As SqlCeException
   MessageBox.Show("Could not load " + tableName + " (" + _
       ex.Message + ")!", "Fill ComboBox")
 End Try
End Sub

.NET Compact Framework 中的方法稍有不同。尽管您可以向 ComboBox 控件中添加自定义项,但更常见的方法是使用数据绑定。数据绑定使用 SqlCeDataAdapter 对象 (da) 加载带有表 (tableName) 的行的 DataSet 对象 (ds)。然后,您可以设置 ComboBox 属性,以选择要显示表中的哪个列 (DisplayMember),以及选择表中的哪个列以用于检索当前选择的值 (ValueMember)。最后,ComboBox 绑定到 DataSet 中的唯一表。

在 C# 中,相同的代码如下所示。

private void loadComboBox(ComboBoxcomboBox, string tableName,
 string valueColumnName, string displayColumnName,
 bool selectFirst)
{
 try
 {
   string sql = "SELECT" + valueColumnName + ", " +
        displayColumnName + " FROM " + tableName +
        " ORDER BY " + displayColumnName;
   SqlCeDataAdapterda = new SqlCeDataAdapter(sql, cn);
   DataSetds = new DataSet();
   da.Fill(ds, tableName);
   comboBox.DisplayMember = displayColumnName;
   comboBox.ValueMember = valueColumnName;
   comboBox.DataSource = ds.Tables[0];
 }
 catch (SqlCeExceptionex)
 {
   MessageBox.Show("Could not load " + tableName + " (" +
     ex.Message + ")!", "Fill ComboBox");
 }
}

既然您已经设置了窗体并且加载了 ComboBox 控件,那么您就可以向定单中添加项了。在原始的 eMbedded Visual Basic 示例中,用于向 ListView 控件中添加定单项的代码如下所示。

Private Sub cmdAdd_Click()
 Dim curProductCost As Currency
 Dim lngProductID As Long
 Dim objDetails
' Make sure the user has selected a product.
 If (cmbProducts.ListIndex < 0) Then
   MsgBox "You must select a product before adding it" & _
           " to the order.", _
           vbInformation, _
           "Add Product"
   Exit Sub
 End If
' Make sure the quantity is valid.
 If (CInt(txtQuantity.Text) <= 0) Then
   MsgBox "You must enter a quantity of 1 or more" & _
           " before adding it to the order.", _
           vbInformation, _
           "Add Product"
   Exit Sub
 End If
' Add the current item to the list.
 Set objDetails = lvwOrder.ListItems.Add(, , _
               cmbProducts.List(cmbProducts.ListIndex))
' Get information about the current product and
' add this information to the current row (the row
' that was just added).
 GetProductInfo cmbProducts.ItemData(cmbProducts.ListIndex), _
                curProductCost
 objDetails.SubItems(1) = curProductCost
 objDetails.SubItems(2) = txtQuantity.Text
 objDetails.SubItems(3) =   cmbProducts.ItemData(cmbProducts.ListIndex)
' Reset the product fields.
 cmbProducts.ListIndex = -1
 txtQuantity.Text = "0"
 hscQuantity.Value = 0
 
End Sub

应用程序进行检查以确保已经在产品的 ComboBox 控件 (cmbCustomer) 中选择了产品,并且输入了有效的数量。然后,应用程序向 ListView 控件中添加一个项,并且将产品名称作为第一列。应用程序通过使用方法调用 (GetProductInfo) 检索所选产品的价格,然后更新新的 ListView 项的其他列(价格、数量和产品标识)。最后,应用程序重置窗体控件,以便它做好输入下一个定单项的准备。

在迁移以后,相同的 Visual Basic .NET 代码如下所示。

Private Sub addButton_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles addButton.Click
 ' Make sure the user has selected a product.
 If productComboBox.SelectedIndex < 0 Then
   MessageBox.Show("You must select a product before adding it" + _
     " to the order.", "Add Product")
   Return
 End If
  ' Create a new list row.
 Dim lvi As ListViewItem= New ListViewItem(productComboBox.Text)
 ' Get information about the current product and
 ' add this information to the new row.
 Dim curProductCost As Double = getProductInfo( _
   Convert.ToInt32(productComboBox.SelectedValue))
 lvi.SubItems.Add(String.Format("{0:##0.00}", curProductCost))
 lvi.SubItems.Add(quantityNumericUpDown.Value.ToString())
 lvi.SubItems.Add(productComboBox.SelectedValue.ToString())
 ' Add the new row to the list.
 orderListView.Items.Add(lvi)
 ' Reset the product fields.
 productComboBox.SelectedIndex = -1
 quantityNumericUpDown.Value = 1
End Sub

您可以使用 .NET Compact Framework 中的 ListView 控件向列表中添加项 (ListViewItem)。因此,首先需要创建一个项,添加所有列,然后才能将其添加到 ListView 控件中。请注意,quantity 字段的初始值设置为 1(与原始的 eMbedded Visual Basic 示例代码相反),因为该值更有可能出现。

在 C# 中,相同的代码如下所示。

private void addButton_Click(object sender, System.EventArgs e)
{
 // Make sure the user has selected a product
 if(productComboBox.SelectedIndex < 0)
 {
   MessageBox.Show("You must select a product before adding it" +
                 " to the order.", "Add Product");
   return;
 }
 // No need to make sure the quantity is valid because the
 // NumericUpDown control takes care of that
 // Create a new list row
 ListViewItemlvi = new ListViewItem(productComboBox.Text);
 // Get information about the current product and
 // add this information to the new row
 double curProductCost = getProductInfo(Convert.ToInt32(
   productComboBox.SelectedValue));
 lvi.SubItems.Add(string.Format("{0:##0.00}", curProductCost));
 lvi.SubItems.Add(quantityNumericUpDown.Value.ToString());
 lvi.SubItems.Add(productComboBox.SelectedValue.ToString());
 // Add the new row to the list
 orderListView.Items.Add(lvi);
 // Reset the product fields
 productComboBox.SelectedIndex = -1;
 quantityNumericUpDown.Value = 1;
}

在原始的 eMbedded Visual Basic 示例中,用于获取产品信息的代码如下所示。

Private Sub GetProductInfo(lngProductID As Long, _
                   curProductCost As Currency)
   Dim rsProduct As ADOCE.Recordset
   Dim strSQLAs String
' Setup an error handler.
   On Error Resume Next
   Err.Clear
' Find the record of the specified product.
   strSQL= "SELECTCost FROM Products " & _
       "WHERE ProductID = " & lngProductID
   Set rsProduct = cnMobileSales.Execute(strSQL)
' Check to see if an error occurred.
   If (Err.Number <> 0) Then
   MsgBox "An error was encountered while attempting" & _
           " to retrieve the product info." & vbCrLf & _
           "Error #" & Err.Number & ", " & _
           Err.Description, vbCritical, "Database Error"
    curProductCost = 0
   Else
    curProductCost = rsProduct.Fields("Cost")
   End If
' Clean up before exiting.
   rsProduct.Close
   Set rsProduct = Nothing
   On Error GoTo 0
End Sub

应用程序检索产品 ADOCE.Recordset (rsProduct),并且如果没有发生任何错误,则应用程序会返回该产品的价格。

在迁移以后,相同的 Visual Basic .NET 代码如下所示。

Private Function getProductInfo(ByVal productID As Integer) As Double
 Dim curProductCost As Double
 Try
   ' Find the record of the specified product.
   Dim sql As String = "SELECTCost FROM Products" + _
           " WHERE ProductID = " + productID.ToString()
   Dim cmd As SqlCeCommand= New SqlCeCommand(sql, cn)
   curProductCost = Convert.ToDouble(cmd.ExecuteScalar())
 Catch ex As SqlCeException
   MessageBox.Show("An error was encountered while attempting" + _
           " to retrieve the product info." + vbCrLf + _
           "Error: " + ex.Message + "!", "Database Error")
   curProductCost = 0
 End Try
 Return curProductCost
End Function

ADO.NET 可以使用 SqlCeCommand 对象获得只包含一个值的结果。应用程序使用该结构 (ExecuteScalar) 获得产品价格。

在 C# 中,相同的代码如下所示。请注意,在 Visual Basic .NET 代码中,由函数而不是更新的参数返回成本,从而使得代码更易于阅读和理解。

private double getProductInfo(int productID)
{
 double curProductCost;
 try
 {
   // Find the record of the specified product
   string sql = "SELECTCost FROM Products" +
          " WHERE ProductID = " + productID.ToString();
   SqlCeCommandcmd = new SqlCeCommand(sql, cn);
   curProductCost = Convert.ToDouble(cmd.ExecuteScalar());
 }
 catch (SqlCeExceptionex)
 {
   MessageBox.Show("An error was encountered while attempting" +
         " to retrieve the product info.
" +
         "Error: " + ex.Message + "!", "Database Error");
   curProductCost = 0;
 }
 return curProductCost;
}

尽管上述代码中未显示,但还可以从定单中移除项。有关详细信息,请参阅 deleteButton 的 Click 事件中的示例代码。

既然已经在定单中添加(也可能移除)了项,那么您就可以保存该定单了。在原始的 eMbedded Visual Basic 示例中,用于保存新定单的代码如下所示。

Private Sub SaveOrder()
' This routine saves this current order to the database.
 Dim curProductCost As Currency
 Dim intCounter As Integer
 Dim intErrors As Integer
 Dim lngProductID As Long
 Dim strSQLAs String
' Set up an error handler.
 On Error Resume Next
 Err.Clear
' Store the individual items for this order.
 For intCounter = 1 To lvwOrder.ListItems.Count
' Place the information into the database.
   strSQL= "INSERT INTO Orders (CustomerID, ProductID," & _
      " Quantity) VALUES (" &       cmbCustomers.ItemData(cmbCustomers.ListIndex) & ", " & _
      lvwOrder.ListItems(intCounter).SubItems(3) & ", " & _
      lvwOrder.ListItems(intCounter).SubItems(2) & ")"
   cnMobileSales.Execute strSQL
' Check to see if an error occurred.
   If (Err.Number <> 0) Then
     For intErrors = 1 To cnMobileSales.Errors.Count
       MsgBox cnMobileSales.Errors(intErrors).Number & _
        " - " & _
        cnMobileSales.Errors(intErrors).Description, _
        vbCritical, _
        "Save Order"
     Next intErrors
     Err.Clear
     On Error GoTo 0
     Exit Sub
   End If
 Next intCounter
' Clean up before exiting.
 lvwOrder.ListItems.Clear
 cmbCustomers.RemoveItem cmbCustomers.ListIndex
 cmbCustomers.Refresh
 If (cmbCustomers.ListCount > 0) Then
   cmbCustomers.ListIndex = 0
 Else
   MsgBox "All customers have been processed.", _
           vbInformation, "Save Order"
   App.End
 End If
 cmbProducts.ListIndex = -1
 txtQuantity.Text = "0"
 MsgBox "The order has been saved.", vbInformation, _
        "Save Order"
 On Error GoTo 0
End Sub

对于 ListView 中的每个列,应用程序都通过使用连接对象 (cnMobileSales) 来执行 SQL 插入语句 (Execute),以便插入新的定单项。应用程序从 ComboBox 控件中检索客户标识,从 ListView 中的每个行中检索产品标识和数量。在将所有定单项添加到数据库中以后,应用程序从 ComboBox 控件中移除客户,并且重置窗体以便输入下一份定单。在输入最后一份定单以后,应用程序关闭。

在迁移以后,相同的 Visual Basic .NET 代码如下所示。

Private Sub saveMenuItem_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles saveMenuItem.Click
 ' Store the individual items for this order.
 Dim lvi As ListViewItem
 For Each lvi In orderListView.Items
   Try
     Dim sql As String = "INSERT INTO Orders (CustomerID," + _
                " ProductID, Quantity) VALUES (" + _
       customerComboBox.SelectedValue.ToString() + ", " + _
       lvi.SubItems(3).Text + ", " + _
       lvi.SubItems(2).Text + ")"
     Dim cmd As New SqlCeCommand(sql, cn)
     cmd.ExecuteNonQuery()
   Catch ex As SqlCeException
     MessageBox.Show("An error was encountered while attempting" + _
       " to save the order." + vbCrLf + _
       "Error: " + ex.Message + "!", "Save Order")
   End Try
 Next
 ' Clean up before exiting.
 orderListView.Items.Clear()
 Dim dt As DataTable= (CType(customerComboBox.DataSource, DataTable))
 dt.Rows(customerComboBox.SelectedIndex).Delete()
 dt.AcceptChanges()
 If dt.Rows.Count > 0 Then
   customerComboBox.SelectedIndex = 0
 Else
   MessageBox.Show("All customers have been processed.", _
     "Save Order")
   Me.Close()
   Return
 End If
 productComboBox.SelectedIndex = -1
 quantityNumericUpDown.Value = 1
 MessageBox.Show("The order has been saved.", "Save Order")
End Sub

.NET Compact Framework 使用 SqlCeCommand 对象的方法来执行 SQL 语句。该方法不返回任何结果 (ExecuteNonQuery)。请注意,在 .NET Compact Framework 中,DataTable 对数据进行管理,而不是依赖于用户界面作为数据存储;在原始的 eMbedded Visual Basic 实现中也是如此。让 DataTable 管理数据可以使代码健壮得多,因为它将数据存储区与数据显示分开。

在 C# 中,相同的代码如下所示。

private void saveMenuItem_Click(object sender, System.EventArgs e)
{
 // Store the individual items for this order
 foreach(ListViewItemlvi in orderListView.Items)
 {
   try
   {
     string sql = "INSERT INTO Orders (CustomerID, ProductID," +
       " Quantity) VALUES (" +
       customerComboBox.SelectedValue.ToString() + ", " +
       lvi.SubItems[3].Text + ", " +
       lvi.SubItems[2].Text + ")";
     SqlCeCommandcmd = new SqlCeCommand(sql, cn);
     cmd.ExecuteNonQuery();
   }
   catch (SqlCeExceptionex)
   {
     MessageBox.Show("An error was encountered while attempting" +
       " to save the order.
" +
       "Error: " + ex.Message + "!", "Save Order");
   }
 }
 // Clean up before exiting
 orderListView.Items.Clear();
 DataTabledt = ((DataTable)customerComboBox.DataSource);
 dt.Rows[customerComboBox.SelectedIndex].Delete();
 dt.AcceptChanges();
 if(dt.Rows.Count > 0)
   customerComboBox.SelectedIndex = 0;
 else
 {
   MessageBox.Show("All customers have been processed.",
     "Save Order");
   this.Close();
   return;
 }
 productComboBox.SelectedIndex = -1;
 quantityNumericUpDown.Value = 1;
 MessageBox.Show("The order has been saved.", "Save Order");
}

正如已经说明的那样,您可以使用标准 SQL 插入语句将行插入到数据库中。对于 SQL update 和 delete 语句也是这样。但是,ADOCE.Recordset 对象在更新数据库之前生成需要的 SQL 语句。尽管在原始的 eMbedded Visual Basic 示例中未包含以下代码,但它显示了一种通过使用 ADO CE 在 eMbedded Visual Basic 中添加新行的替代方式。

Dim rs As ADOCE.Recordset
Set rs = CreateObject("ADOCE.Recordset.3.0")
rs.Open "Orders", cnMobileSales, adOpenDynamic, _
 adLockOptimistic, adCmdTableDirect
rs.AddNew
rs("CustomerID").Value = cmbCustomers.ItemData(cmbCustomers.ListIndex)
rs("ProductID").Value = lvwOrder.ListItems(intCounter).SubItems(3)
rs("Quantity").Value = lvwOrder.ListItems(intCounter).SubItems(2)
rs.Update
rs.Close

要更新 Recordset,您需要指定具有特殊参数 (adCmdTableDirect) 的表名称(不是 SQL 语句)。

等效的 Visual Basic .NET 代码如下所示。

Dim da As New SqlCeDataAdapter("SELECT* FROM Orders", cn)
Dim cb As New SqlCeCommandBuilder(da)
da.InsertCommand = cb.GetInsertCommand()
da.UpdateCommand = cb.GetUpdateCommand()
da.DeleteCommand = cb.GetDeleteCommand()
Dim ds As DataSet= New DataSet
da.Fill(ds, "Orders")
Dim dr As DataRow = ds.Tables("Orders").NewRow()
dr("CustomerID") = Convert.ToInt32(customerComboBox.SelectedValue)
dr("ProductID") = Convert.ToInt32(lvi.SubItems(3).Text)
dr("Quantity") = Convert.ToInt32(lvi.SubItems(2).Text)
ds.Tables("Orders").Rows.Add(dr)
da.Update(ds, "Orders")

ADO.NET 命令生成器 (SqlCeCommandBuilder) 包含 ADOCE.Recordset 对象中内置的数据操作逻辑。应用程序使用命令生成器 (cb) 对象,根据提供给数据适配器 (da) 的选择命令 (SELECT * FROM Orders) 生成需要的命令(insert、update 和 delete)。生成的命令如下所示:

INSERT INTO Orders (CustomerID,ProductID,Quantity) VALUES (?,?,?)
UPDATE Orders SET CustomerID=?,ProductID=?,Quantity=? WHERE OrderID=?
DELETE FROM Orders WHERE OrderID=?

命令生成器将 select 命令与从数据库中检索的信息(主键)一起使用,以生成其他命令。

在 C# 中,相同的代码如下所示。

SqlCeDataAdapterda = new SqlCeDataAdapter("SELECT* FROM Orders", cn);
SqlCeCommandBuildercb = new SqlCeCommandBuilder(da);
da.InsertCommand = cb.GetInsertCommand();
da.UpdateCommand = cb.GetUpdateCommand();
da.DeleteCommand = cb.GetDeleteCommand();
DataSetds = new DataSet();
da.Fill(ds, "Orders");
DataRow dr = ds.Tables["Orders"].NewRow();
dr["CustomerID"] = Convert.ToInt32(customerComboBox.SelectedValue);
dr["ProductID"] = Convert.ToInt32(lvi.SubItems[3].Text);
dr["Quantity"] = Convert.ToInt32(lvi.SubItems[2].Text);
ds.Tables["Orders"].Rows.Add(dr);
da.Update(ds, "Orders");

在该示例的迁移过程中,移除了很多行代码,因为 Visual Studio .NET 开发环境中的窗体设计器现在处理了很多以前必须在 eMbedded Visual Basic 中实现的任务。.NET Compact Framework 中的错误处理具有更高结构性的这一事实也节省了很多行代码。

小结

将以前的 Pocket PC 应用程序迁移到当前工具集的原因很多。该工具集还为开发人员和应用程序用户带来了新的机会。本文可能为您提供足够的理由,以便让您的股东相信这一迁移不仅是可能的,而且可以带来相当高的投资回报率。

上一页  1 2 3 

Tags:Pocket Access SQL

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接