System.Data.SQLiteには、.NET Compact Framework用のクラスライブラリ(こちらも接続コンポーネントではなくSQLiteそのもの)も付属しています。
Windows Mobileアプリを新規に作成して、実機(emone α)に配置して動作するかどうかを確認してみます。
サンプル用プロジェクトの作成
.NET Framework 2.0でWindows Mobile 5.0 Pocket PC SDKをターゲットにしてあたらしいプロジェクトを作成します。
参照設定で、System.Data.SQLite.dllを指定します。ここで表示されているのは.NET Compact Framewok用のクラスライブラリだけですので、クラスライブラリの場所も.NET Compact Framework用のものであることが分かります。
System.Data.SQLite.dllは、配置の事を考慮してローカルにコピーするように設定します。
さらに「」で作成したtest.dbファイルもプロジェクトに加えて、[出力ディレクトリにコピー]プロパティを「新しいときはコピーする」に設定します。

これで、プロジェクトの準備はできました。
Visual Basic 2008でプログラミングする
System.Data.SQLiteは、ADO.NET 2.0相当のデータアクセスメソッドをもっているので、VB2005でもVB2008でも同じようにプログラミングできます。そこで次のような画面をもつサンプルプログラムを作成して、接続、データ取得、データ更新のコードを確認してみましょう。
SQLiteのファイルと接続する
Imports System.Data.SQLite
Public Class SampSQLite
Private Ds As New DataSet
Private ConnectionString As String = "data source={0}"
Private Sub SampSQLiteCF_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
ConnectionString = String.Format(ConnectionString, _
System.IO.Path.Combine(GetCurrentDirectory, _
"test.db"))
End Sub
Private Shared Function GetCurrentDirectory() As String
Dim fqn As String = System.Reflection.Assembly. _
GetExecutingAssembly. _
ManifestModule. _
FullyQualifiedName
Return New System.IO.FileInfo(fqn).DirectoryName
End Function
Private Sub Connect_Button_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Connect_Button.Click
Cursor.Current = Cursors.WaitCursor
Using _cn As New SQLiteConnection
Try
_cn.ConnectionString = ConnectionString
_cn.Open()
MessageBox.Show("Open成功", Me.Text)
Catch ex As Exception
MessageBox.Show(ex.Message, Me.Text)
Finally
Try
_cn.Close()
Catch ex As Exception
End Try
Cursor.Current = Cursors.Default
End Try
End Using
End Sub
End Class
カレントディレクトリを取得する部分だけは.NET Compact Frameworkに合わせて書き足してはいますが、その他の部分についてはWindowsアプリケーションのときと同一のコードです。
Windows Mobile 5.0 Pokect PC R2 エミュレータでの動作確認
エミュレータに対して配置を行っても、アセンブリだけは配置されますが、System.Data.SQLite.dllやtest.dbは配置されません。
そこで[ファイル]-[構成]メニューをクリックして共有フォルダを設定して、エミュレータのファイルエクスプローラで不足しているファイルを手動配置します。
エミュテータを使う場合、作成したアセンブリとtest.db(SQLiteファイル)のみで動作します。
実機(emone α)の動作確認
PC同期モードでUSBを接続してからアセンブリを配置したら、test.db(SQLiteファイル)を含め次のファイルをコピーします。
- System.Data.SQLite.dll(114KB)
- SQLite.Interop.060.DLL(438KB)
- test.db
SQLiteのテーブルから値を取得する
ADO.NETを使ってテーブルから値を取得する方法には、DataReaderを使う方法とDataAdapterを使う方法があります。ここでは、DataAdapterを使う方法をご紹介します。
Imports System.Data.SQLite
Public Class SampSQLite
Private Ds As New DataSet
Private ConnectionString As String = "data source={0}"
Private Sub SampSQLiteCF_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
ConnectionString = String.Format(ConnectionString, _
System.IO.Path.Combine(GetCurrentDirectory, _
"test.db"))
End Sub
Private Shared Function GetCurrentDirectory() As String
Dim fqn As String = System.Reflection.Assembly. _
GetExecutingAssembly. _
ManifestModule. _
FullyQualifiedName
Return New System.IO.FileInfo(fqn).DirectoryName
End Function
Private Sub GetRecords_Button_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles GetRecords_Button.Click
Cursor.Current = Cursors.WaitCursor
Using _cn As New SQLiteConnection
Try
_cn.ConnectionString = ConnectionString
_cn.Open()
Using _cmd As New SQLiteCommand("SELECT * FROM EMP", _cn)
Using _da As New SQLiteDataAdapter(_cmd)
_da.Fill(Ds, "EMP")
Me.Result_Grid.DataSource = Ds.Tables("EMP")
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, Me.Text)
Finally
Try
_cn.Close()
Catch ex As Exception
End Try
Cursor.Current = Cursors.Default
End Try
End Using
End Sub
End Class
データを取得するためには、以下の手順を実行します。
- SQLiteConnectionをOpen SQLiteCommandにSELECT文を設定
- SELECT文を設定したSQLiteCommandを指定してSQLiteDataAdapterを生成
- SQLiteDataAdatpterのFilllメソッドによりDataSetにレコード設定
DataSetに入ってしまえば、データの取得元は関係なくなりますので、DataGridViewのデータソースとして指定すればテーブルの内容をグリッド表示できます。
SQLiteのテーブルの値を更新する
Imports System.Data.SQLite
Public Class SampSQLite
Private Ds As New DataSet
Private ConnectionString As String = "data source={0}"
Private Sub SampSQLite_Shown(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles Me.Shown
ConnectionString = String.Format(ConnectionString, _
System.IO.Path.Combine(My.Application.Info.DirectoryPath, _
"test.db"))
End Sub
Private Sub SetRecords_Button_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles SetRecords_Button.Click
Cursor.Current = Cursors.WaitCursor
Using _cn As New SQLiteConnection
Try
_cn.ConnectionString = ConnectionString
_cn.Open()
Using _tr As SQLiteTransaction = _cn.BeginTransaction
Try
Using _cmd As New SQLiteCommand("SELECT * FROM EMP", _cn)
_cmd.Transaction = _tr '###重要###
Using _da As New SQLiteDataAdapter(_cmd)
Using cb As New SQLiteCommandBuilder(_da)
cb.SetAllValues = False
cb.ConflictOption = Data.ConflictOption.OverwriteChanges
_da.UpdateCommand = cb.GetUpdateCommand()
_da.InsertCommand = cb.GetInsertCommand()
_da.DeleteCommand = cb.GetDeleteCommand()
MessageBox.Show(_da.UpdateCommand.CommandText, Me.Text)
MessageBox.Show(_da.InsertCommand.CommandText, Me.Text)
MessageBox.Show(_da.DeleteCommand.CommandText, Me.Text)
_da.Update(Ds, "EMP")
MessageBox.Show("Update", Me.Text)
End Using
End Using
End Using
_tr.Commit()
Catch ex As Exception
MessageBox.Show(ex.Message, Me.Text)
_tr.Rollback()
Finally
End Try
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, Me.Text)
Finally
Try
_cn.Close()
Catch ex As Exception
End Try
End Try
Cursor.Current = Cursors.Default
End Using
End Sub
End Class
残念ながら、.NET Compact FrameworkのDataGridはデータ参照のみで更新ができません。更新するためには、更新用別画面を作成することになるようです。
今回は省略しますが、別画面で設定した値をDataSetに反映させれば、あとはこのコードで更新が行えます。
このコードで重要な点はつぎのような事になります。
DataSetからの反映にもSQLiteDataAdapterを使いますが、SELECT文ではなくUPDATE、INSERT、DELETEのSQL文が必要です。重要なのは、反映時にどのSQL文を使うかはSQLiteDataAdapterの内部実装になるので、必ず3つとも設定しておかないと実行時にエラーが発生する危険性があることを忘れないようにしてください。
3つのSQL文はそれぞれ記述してもいいのですが、SQLiteCommandBuilderを使って、SELECT文から自動生成するのが楽です。
SetAllValuesプロパティとConflictOptionプロパティをサンプルコードのように設定すれば次のようなSQL文を生成してくれます。
DataAdapterでの更新にはトランザクションを設定が必須
SQLiteに限らず、ADO.NETのDataAdapterでデータ更新をする場合、かならず明示的にトランザクションを開始して、Updateメソッドが成功したらCommit、失敗したらRollBackする必要があります。
なぜならば、データ更新対象が常に1つになるような画面構成ならば1SQL文の実行ですみますが、グリッド表示のように削除、追加、複数行の変更が行われる可能性がある場合、DataAdapterのUpdateメソッドの内部ではUPDATE、INSERT、DELETEのSQL文を別個に発行しているからです。
これは非常に重要な点です。忘れないようにしましょう。