您的位置:首页 > 数据库

智能设备扩展、SQL Server CE 和我

2008-11-25 18:16 211 查看
下载 Northwind_mobile.exe
我越来越迷恋上了电视节目了。在你们询问“这家伙是怎么回事?”之类的电子邮件雪片般飞过来之前,我自己先做一番解释。

客观上讲,我知道电视节目的时间长度都是一样的。实际上,我已经算出它们的长度一样。电视可以使我摆脱家里的所有时钟。我将电视节目作为日晷的一种新式日用替代品。Gunsmoke
位于 TVL;它上映时就是午餐时间。Trading Spaces 是 TLC
的一档节目;它播出时就是该去跑步的时间了。Baseball Tonight 是 ESPN 的一档节目;它播出时就该关闭
Pocket PC 结束一天的工作了。

令我感到气恼的是电视节目制作人让特定节目所包含的内容不断在缩水。他们是怎么做的呢?他们播放前几周的精彩镜头,通过这种恶毒手段欺骗观众。我敢断言,一些极有前途的制作人心里很清楚:播放老节目比制作新内容轻松得多。以前只有聪明的孩子才会玩的“瞒天过海”这种把戏现在开始在许多电视节目上出现了。
现在不要让我犯错误。这种手法在工作中有着很好、很实际的应用。请先听我讲解片刻。上司问您这周做了哪些事情,而您就把前几周做的事情都算在内。这会使他们瞎猜。如果他们追着您问您在一个紧急的项目中做了哪些工作,您只需把前几个月做的事情统统倒出来就行了。不断地切换内容(我做了这个,我做了那个),并以电影预告片中的低沉声调表述出来。天啊,这样也许您就真的不必再做新的工作了。而只从已经做的工作中领取薪酬就行了。
关于试图颠覆美国社会基础的行为就到此为止,我们还是继续探讨智能设备扩展 (SDE),并初步介绍如何通过 SQL Server CE (SQLCE) 使用 SDE。
SDE + SQLCE =
移动数据
在我最近一次专栏中,我向您介绍了如何通过 SDE 构建一个简单的 Hello World
应用程序。现在,我知道这种应用程序的市场是极其有限的,要以 $9.95 的价格售出 10,000 份副本是十分困难的。所以这个月我将着重介绍一些比较实用的内容 — 通过 SDE 使用
SQLCE。
在开始介绍之前,我先说明一下,使用 SDE 处理数据与通过 eMbedded Visual Basic? 处理数据的差别很大。如果采用 eMbedded Visual Basic,您可以使用两种类型的数据库 — Pocket Access 和
SQLCE。许多开发人员选择使用 Pocket Access,因为它容易实现,而且与 Microsoft Access 相集成。而 SDE 只支持
SQLCE。在 eMbedded Visual Basic 中,您具有 ADOCE。SDE 提供 ADO.NET。
现在,我将深入分析对 ADO.NET
和 .NET Compact Framework
的一个不切实际的诽谤。不瞒您说,那些类型的文章着实令我头痛。相反,在本文及后续一些文章中,我将通过一些示例向您演示在构建移动应用程序中经常需要用到的一些功能和特性。
SDE
样式的 Northwind Mobile
我将通过一个称为 Northwind Mobile 的简单应用程序来向您介绍 SDE 和
SQLCE。这个应用程序的名称来源于在其上构建它的数据库 — 有名的 Northwind 数据库。我不知道您对它有什么感觉,反正 Northwind
是我最喜欢的数据库。事实上,在网络泡沫膨胀之际,我经营了一家电子商务公司,它提供一组专门处理 Northwind 数据库的服务。这次尝试的收获就是发现公司需要 Northwind 数据库的唯一原因是:它是由 Microsoft
提供的。虽然幸运地拥有这个公司,但它还是破产了,这主要有两个原因:
每个人都已经拥有 Northwind 的副本了。
没有人需要在关键地方使用它。
Northwind Mobile 概述
Northwind Mobile
是一个简单的应用程序。它的唯一功能是显示存储在本地 SQL Server CE
数据库中的定单。它拥有一个客户列表,您可以从中挑选。当您选择客户时,会构建他们的定单列表。从这个列表中选择一个定单可以显示定单的详细信息。图 1
显示了使用中的一个示例 Northwind Mobile 应用程序。



[b]图 1. Northwind
Mobile
应用程序 [/b]
Northwind Mobile
的界面
Northwind Mobile 界面由七个控件组成:两个 ComboBox、两个 Label、两个 TextBox 和一个 ListView。图
2 显示了 SDE 窗体设计器的界面。



[b]图 2. Northwind
Mobile
界面设计 [/b]
Northwind Mobile
数据库
我前面已经提到,Northwind Mobile 应用程序使用 SQL Server CE
数据库。事实上,创建数据库也是它的一部分功能。我为什么使用这种方案呢?只是因为它是 SDE 和 SQLCE 入门的最简单途径。是的,我知道 SQLCE
提供了大量功能来从 SQL Server 数据库检索数据。尽管如此,有时您只需要一个本地数据库就可以了。要学会的是如何创建这个数据库。有两种方法:

通过代码创建数据库。
使用 SQLCE Query 工具创建数据库。

我们首先来看通过代码创建数据库这种方法。
通过代码构建数据库
您需要先在项目中添加对 System.Data.SqlServerCe
组件的引用,然后才可以在 SDE 应用程序中使用 SQLCE 数据库。可以这样来实现:在开发环境中,从 Project
菜单中选择 Add Reference…。然后从 Add Reference 对话框中选择
System.Data.SqlServerCe 组件,如图 3 所示。



[b]图 3.
Add Reference
对话框选择 System.Data.SqlServerCe
组件 [/b]
Northwind Mobile 应用程序中的 CreateDatabase
例程演示了如何通过代码创建数据库。当应用程序启动时就会调用这个例程。
在 CreateDatabase
顶部,可以看到一小块注释代码。我是出于调试目的添加的,并考虑到也许对您有用而决定留下它。它演示了如何检查一个文件是否存在,以及如何删除一个文件。
Private
Sub CreateDatabase() Dim cn As System.Data.SqlServerCe.SqlCeConnection Dim
SQL As String Dim SQLEngine As System.Data.SqlServerCe.Engine' If the
database exists, blow it away.' If System.IO.File.Exists("\My
Documents\Northwind.sdf") Then' System.IO.File.Delete("\My
Documents\Northwind.sdf")' End
If
进行检查是为了确定数据库是否存在。如果不存在,就创建它。此时数据库是空的,因此没有结构或内容。
' If the database does
not already exist, then create it. If Not System.IO.File.Exists("\My
Documents\Northwind.sdf") Then SQLEngine = New
System.Data.SqlServerCe.Engine _ ("data source=\My
Documents\Northwind.sdf") SQLEngine.CreateDatabase()
既然数据库已经存在,就可以打开它。
'
Next, open the database. cn = New
_ System.Data.SqlServerCe.SqlCeConnection("Provider=Microsoft.SQLServer.O
_ LEDB.CE.1.0;Data Source=\My
Documents\Northwind.sdf") cn.Open()
使用一组 SQL CREATE
TABLE
语句定义表及其相关字段。这个示例只包含四个原始的 Northwind
表:Customers、Orders、OrderDetails 和 Products。
' Now, through a series of SQL
statements create the structure of the database.' Create the Customers
table. SQL = "CREATE TABLE Customers (CustomerID nchar(5) Primary Key
_ NOT NULL,CompanyName nvarchar(40) NOT NULL)" Dim cmd As New
System.Data.SqlServerCe.SqlCeCommand(SQL, cn) cmd.CommandType =
CommandType.Text cmd.ExecuteNonQuery()' Create the Orders table. SQL =
"CREATE TABLE Orders (OrderID int Primary Key NOT _ NULL,CustomerID
nchar(5) NOT NULL,OrderDate datetime _ NULL,ShippedDate datetime
NULL)" cmd.CommandText = SQL cmd.ExecuteNonQuery()' Create the
OrderDetails table. SQL = "CREATE TABLE OrderDetails (OrderID int NOT
NULL,ProductID _ int NOT NULL,UnitPrice money NOT NULL,Quantity smallint
NOT _ NULL,Discount real NOT NULL)" cmd.CommandText =
SQL cmd.ExecuteNonQuery()' Create the Products table. SQL = "CREATE
TABLE Products (ProductID int Primary Key NOT _ NULL,ProductName nvarchar
(40) NOT NULL)" cmd.CommandText =
SQL cmd.ExecuteNonQuery()
此时数据库有了基本的结构,但没有数据。我准备使用大量 SQL
INSERT
语句对其进行修改,这些语句的作用是将一组测试数据加载到数据库中。再次声明,这些只是原始的 Northwind
数据库中的一部分数据。您可以认为它是 Northwind 简化版。
为了节省空间,对于每个表,我将 SQL INSERT 语句缩减为一条
INSERT 语句。对于那些有兴趣而且有大量时间的读者,可以在文章顶部下载 Northwind Mobile
示例项目,查看所有的 INSERT 语句,并引以为豪。
' Next, through a far greater
set of SQL statements load some content into the database.' Load the Customers
table. SQL = "INSERT INTO Customers (CustomerID, CompanyName) VALUES
_ ('ALFKI','Alfreds Futterkiste')" cmd.CommandText =
SQL cmd.ExecuteNonQuery()' Load the Orders table. SQL = "INSERT INTO
Orders (OrderID, CustomerID, OrderDate, _ ShippedDate) VALUES
(10643,'ALFKI','1997-08-25 00:00:00', _ '1997-09-02
00:00:00')" cmd.CommandText = SQL cmd.ExecuteNonQuery()' Load the
OrderDetails table. SQL = "INSERT INTO OrderDetails (OrderID, ProductID,
UnitPrice, _ Quantity, Discount) VALUES
(10643,28,45.6,15,0.25)" cmd.CommandText = SQL cmd.ExecuteNonQuery()'
Load the Products table. SQL = "INSERT INTO Products (ProductID,
ProductName) VALUES (1,'Chai')" cmd.CommandText =
SQL cmd.ExecuteNonQuery()' Close the database. cn.Close() End
If End Sub

使用 SQLCE 查询构建数据库
当您在设备中安装 SQL Server CE 2.0 测试版以及 SQLCE 本身一些零碎的文件之后,您就获得了一个叫做
SQLCE Query 的工具。为方便访问,将它放在了 Start菜单中。通过这个工具,您可以在设备中创建和查询 SQLCE
数据库。现在要承认,由于这个工具要求您使用 SIP(软输入面板),所以它可能让您短寿 5 到 7 年,但如果您有一个 Targus 键盘或者一个桌面实用工具(如
Pocket Controller (http://www.soti.net/)),则它可以工作得很好。这个工具对于调试任何基于 SQLCE
的应用程序很有帮助,并且在必要时可以创建与您的应用程序配套的数据库。图 4 显示了 SQLCE Query 界面的一个示例。



[b]图 4. SQLCE
Query
应用程序 [/b]
走进 Northwind
Mobile
既然我们有了数据库,我将带您走进组成 Northwind Mobile 应用程序的各个例程。
启动应用程序
Northwind
Mobile 的加载事件过程执行以下三个功能:
在必要时创建数据库。
设置 ListView 控件的格式。
加载客户列表。

Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As
_ System.EventArgs) Handles MyBase.Load' Check to see if the database exists.
If it does not exist it will be created. CreateDatabase()' Format the
ListView control. FormatListView()' Load the Customer combo
box. LoadCustomers() End Sub
我们已经看过了 CreateDatabase 例程。接下来简要看一下
FormatListView 和 LoadCustomers。
设置 ListView 控件的格式
对 ListView
控件进行一些简单的格式设置,使它具有列标题,并设置列宽。此处也对应用程序要使用的视图 — 详细信息视图进行了格式设置。
Private Sub
FormatListView()' This routine handles configuring the listview
control. lvwOrder.View = View.Details lvwOrder.Columns.Add("Product", 120,
HorizontalAlignment.Left) lvwOrder.Columns.Add("Qty", 40,
HorizontalAlignment.Right) lvwOrder.Columns.Add("Price", 50,
HorizontalAlignment.Right) lvwOrder.Columns.Add("Disc", 50,
HorizontalAlignment.Right) lvwOrder.Columns.Add("Total", 60,
HorizontalAlignment.Right) End Sub
加载客户列表
LoadCustomers 例程让我们初步了解了如何从
SQLCE 数据库检索数据。
Private Sub LoadCustomers() Dim cn As
System.Data.SqlServerCe.SqlCeConnection Dim cmd As
System.Data.SqlServerCe.SqlCeCommandDim dtr As
System.Data.SqlServerCe.SqlCeDataReader
首先打开数据库。此处除了指定 Northwind 数据库的位置,还指定了
SQLCE 提供程序。
' Open the database. cn = New
_ System.Data.SqlServerCe.SqlCeConnection("Provider=Microsoft.SQLServer.
_ OLEDB.CE.1.0;Data Source=\My
Documents\Northwind.sdf") cn.Open()
SQL SELECT
语句用于检索所有客户,并将结果放在 DataReader 对象中。
' Retrieve a list of the
customers. cmd = New System.Data.SqlServerCe.SqlCeCommand("SELECT * FROM
Customers", cn) dtr =
cmd.ExecuteReader()
DataReader对象的功能很像一个只进、只读的记录集。它允许您单向遍历一组记录,并专门为加载
ComboBox 而设计的。
' Load the list into the customer combo
box. cmbCustomers.Items.Clear() While
dtr.Read() cmbCustomers.Items.Add(dtr("CompanyName")) End
While
当我们关闭数据库对象并从 ComboBox 中选择第一个客户时,LoadCustomers
例程就执行完毕。选择第一个客户会初始化一连串事件,这些事件会加载客户的定单并显示其中一个。
'
Clean-up. dtr.Close() cn.Close()' Select the first
customer. cmbCustomers.SelectedIndex = 0 End
Sub
加载定单列表
选择一个客户就会加载该客户的定单列表。这是由 LoadOrders 例程执行的。从功能上讲,这个例程与
LoadCustomers 很相似,但比 SQL SELECT 语句略微有些复杂,它演示了 SQL Server CE 对
SQL INNER JOIN 语句的支持。
Private Sub LoadOrders() Dim cn As
System.Data.SqlServerCe.SqlCeConnection Dim cmd As
System.Data.SqlServerCe.SqlCeCommand Dim dtr As
System.Data.SqlServerCe.SqlCeDataReader Dim SQL As String' Open the
database. cn = New
System.Data.SqlServerCe.SqlCeConnection("Provider=Microsoft.SQLServer.
_ OLEDB.CE.1.0;Data Source=\My Documents\Northwind.sdf") cn.Open()' Retrieve
the orders for the selected customer. SQL = "SELECT Orders.OrderID FROM
Orders INNER JOIN Customers ON " SQL = SQL & "Orders.CustomerID =
Customers.CustomerID WHERE " SQL = SQL & "(Customers.CompanyName = '"
& cmbCustomers.Text SQL = SQL & "')" cmd = New
System.Data.SqlServerCe.SqlCeCommand(SQL, cn) dtr = cmd.ExecuteReader()' Load
the list into the order combo box. cmbOrders.Items.Clear() While
dtr.Read() cmbOrders.Items.Add(dtr("OrderID")) End While'
Clean-up. dtr.Close() cn.Close() End Sub
加载定单详细信息
当选择一个定单时,就会首先从
SQLCE 数据库检索该定单的详细信息,然后加载到 ListView 控件中。这些功能是由 LoadOrderDetails 例程执行的。与
LoadCustomers 和 LoadOrders 例程一样,LoadOrderDetails 例程的核心内容包含两条 SQL
SELECT
语句。一条用于捕获定单的摘要信息,另一条用于恢复选定的定单所包含的各个项目。
Private Sub
LoadOrderDetails() Dim cn As System.Data.SqlServerCe.SqlCeConnection Dim
cmd As System.Data.SqlServerCe.SqlCeCommand Dim Discount As Single Dim dtr
As System.Data.SqlServerCe.SqlCeDataReader Dim ItemTotal As Single Dim
LVItem As ListViewItem Dim OrderTotal As Single Dim Quantity As
Int16 Dim SQL As String Dim UnitPrice As Single' Open the database. cn
= New
System.Data.SqlServerCe.SqlCeConnection("Provider=Microsoft.SQLServer._ OLEDB.CE.1.0;Data
Source=\My Documents\Northwind.sdf") cn.Open()' Retrieve the order summary
information. SQL = "SELECT OrderDate, ShippedDate FROM Orders WHERE " SQL
= SQL & "OrderID = " & cmbOrders.Text cmd = New
System.Data.SqlServerCe.SqlCeCommand(SQL, cn) dtr =
cmd.ExecuteReader() dtr.Read() txtOrdered.Text =
dtr("OrderDate") txtShipped.Text = dtr("ShippedDate") dtr.Close()'
Retrieve the order details for the selected order. SQL = "SELECT
OrderDetails.UnitPrice, OrderDetails.Quantity, " SQL = SQL &
"OrderDetails.Discount, Products.ProductName FROM OrderDetails " SQL = SQL
& "INNER JOIN Products ON " SQL = SQL & "OrderDetails.ProductID =
Products.ProductID WHERE " SQL = SQL & "OrderDetails.OrderID = " &
cmbOrders.Text cmd = New System.Data.SqlServerCe.SqlCeCommand(SQL, cn)dtr =
cmd.ExecuteReader()
与使用 eMbedded Visual Basic 的情况一样,SDE ListView
控件不能很直观地处理。下面可以看到这个过程:首先创建一个新项,添加到列表中;然后将各个值加载到此项中;最后是如何将该项添加到 ListView
控件中。
' Load the order details into the ListView
control. lvwOrder.Items.Clear() While dtr.Read() LVItem = New
ListViewItem() LVItem.Text = dtr("ProductName") Quantity =
dtr("Quantity") LVItem.SubItems.Add(Quantity.ToString) UnitPrice =
dtr("UnitPrice") LVItem.SubItems.Add(UnitPrice.ToString("N2")) Discount
=
dtr("Discount") LVItem.SubItems.Add(Discount.ToString("N2")) ItemTotal
= Quantity * UnitPrice * Discount OrderTotal = OrderTotal +
ItemTotal LVItem.SubItems.Add(ItemTotal.ToString("N2")) lvwOrder.Items.Add(LVItem) End
While
这样就在 ListView 控件中添加了完整的一行,从而完成定单详细信息的显示。
' Add the total for the
order. LVItem = New ListViewItem() LVItem.Text =
"TOTAL" LVItem.SubItems.Add("") LVItem.SubItems.Add("") LVItem.SubItems.Add("") LVItem.SubItems.Add(OrderTotal.ToString("N2")) lvwOrder.Items.Add(LVItem)'
Clean-up. dtr.Close() cn.Close() End Sub
不用的代码
这是 Geraldo Rivera
类型的一种情况。如果您正好是一个代码狂,宁愿浏览代码源也不愿阅读我的文章,您会在 Northwind Mobile 应用程序中找到一个名为
ApplicationLocation
的例程。事实上有趣的是,ApplicationLocation 这个例程什么用处都没有。我从没有以任何方式调用它或引用它。

为什么我要包含它呢?我想向您说明如何在 SDE 中获得与 eMbedded Visual Basic App.Path
等效的语句。在 Northwind Mobile 应用程序中,我在 My Documents 文件夹中创建 Northwind
数据库。在您的应用程序中,您可能需要在驻留应用程序的同一个文件夹中创建一个数据库或者另外创建一个文件。因此这就需要用到
ApplicationLocation。这个示例也能表明有些事情在 SDE 中完成比在 eMbedded Visual
Basic 中完成来得复杂。
Private Function ApplicationLocation() As String' Fetch and
return the location where the application was launched. ApplicationLocation =
_ System.IO.Path.GetDirectoryName(Reflection.Assembly.
_ GetExecutingAssembly().GetName().CodeBase.ToString()) End
Function
Northwind Mobile 摘要
我构建 Northwind Mobile 有两个目的。其一是向您介绍如何通过代码创建
SQLCE 数据库。虽然您不会总是使用这种方法,但当您构建的应用程序没有包含后端 SQL Server 数据库时,这种方法正好可以派上用场。其二是让您知道通过
SDE 使用 SQLCE 数据库十分简单。通常都说 SQLCE 很难使用,很大程度是因为从 SQL Server
数据库检索数据比较复杂。这个应用程序也表明,并不一定需要这样做。
应该意识到,我只是介绍 SDE
的数据访问,这只是它提供的功能中很简单的一部分。还有很多内容有待挖掘。
开始进行 SDE 开发
想要在一周内速成 SDE
吗?我的培训可以帮您实现这个愿望。我提供了为期五天的 SDE 培训班,它为您提供了要速成所需掌握的一切知识。我会向您介绍如何使用 SDE、SQL Server
CE 和 XML 创建健壮的移动解决方案。要获得详细提纲,请访问 www.larryroof.com
返回原路
这就是本月的话题。我已经准备好了紧身潜水衣和跳板准备出发了。报告来自
Huntington Beach,而且不断在增长。下次我将向您介绍使用 SDE 和 SQLCE
的更好方式。到那时候,我就返回了原路。
John Kennedy 白天是 Visual C++
小组中的一名技术作者和编程人员,晚上则是过着秘密生活的 Pocket PC 开发人员。
Larry Rooflarryroof.com的首脑,该公司专门从事移动项目咨询,以及针对 eMbedded
Visual Basic、智能设备扩展和 SQL Server CE 的培训。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: