Windows Phone 8 - 操作SQLite的練習
在WP7.0時有撰寫過<Windows Phone 7 – 下載檔案至Isolated Storage>介紹了IsoatedStorage中放置一個SQLite檔案,
透過SQLite提供的API進行存取,對於當時還未有Local Database時是可以選擇的項目,但到WP7.1就有支援後,
便比較少提到SQLite在WP上的應用。
但對於開發Mobile App可能有些應用是由Android或iOS既有的App移轉支援時,不想重新為一個App建立一個對應
的database時,即會延用另二個平台支援的SQLite做為WP的資料來源,那麼這一篇的介紹可能就變的比較有幫助了。
往下便加以說明,在WP 8環境下,操作SQLite資料庫,至於有沒有適合WP 7.1或7.8呢?下列範例便加以說明;
安裝完上述的SDK後,接著往下透過範例加以說明如何實作一個支援SQLite的WP專案;
(1) 建立一個專案,並加入SQLite SDK的參考:
在建立專案之前,需要安裝一些必要的元件:<Precompiled Binaries for Windows Phone 8>
請先至上述連結下載SQLite的VSIX package,這是Visual Studio的Extension SDK檔,由於只有支援WP8,
所以請透過Visual Studio 2012(或VS Express for Windows phone)開啟該*.vsix檔進行安裝。
=>或者透過Visual Studio中的「Tools/Extensions and Updates」搜尋SQLite進行安裝,如下圖:
安裝完成後,Visual Studio會要求重新啟動,啟動完就安裝完畢了。接下來將它加入專案參考,如下圖:
加以參考後會發現出現警告的畫面,如下圖:
主要是因為專案被設定為「Any CPU」均可以被Compiler,只需要將它改成x86或ARM即可。由於WP 8屬於ARM一種,
所以直接改成ARM即可以正常的編譯。
(2) 將peterhuene / sqlite-net-wp8下載,加入應用程式專案中:
先將檔案下載後,建議放在與應用程式相同的目錄會比較方便參考;接著將它加入專案參考;
(3) 利用 套件管理器主控台 (NuGet library Package Manager Console) 安裝sqlite-net至專案中:
執行指令:「Install-package sqlite-net」;它將會安裝兩個重要的操作檔案:SQLite.cs與SQLiteAsync.cs;
最後一步,在應用程式專案的建置中加入一段:「USE_WP8_NATIVE_SQLITE」,如下圖:
形成:SILVERLIGHT;WINDOWS_PHONE;USE_WP8_NATIVE_SQLITE;
完成以上三個步驟,接著就可以透過這些元件來操作我們的SQLite資料。
A. 建立資料庫與建立資料表;
使用SQLite該類別有個好處,如果指定的PATH合法,但沒有找到指定的檔案時,自動建立資料庫。如下:
private SQLiteConnection gDBConn;
private void InitializationDB()
{
// 指定資料庫位置,如果存在,則使用原有檔案,如果沒有則自動新增。
gDBConn = new SQLiteConnection(Utility.GetLocalFolderDBPath(Utility.DBFileName));
// 建立資料表,根據指定的物件類別
gDBConn.CreateTable<AppConfig>();
GetApplicationConfigData();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
InitializationDB();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
if (gDBConn != null)
{
// 關閉資料庫連線
gDBConn.Close();
}
}
建立資料表時使用的也是物件,但需要在類別中的屬性加上宣告的修飾詞,如同Entity Framework要宣告。
public sealed class AppConfig
{
[PrimaryKey]
public string Id { get; set; }
public string ConfigKey { get; set; }
public string ConfigValue { get; set; }
}
B. 查詢資料表;
private void GetApplicationConfigData()
{
// 利用物件的方式取得資料
List<AppConfig> tApplicationConfig =
gDBConn.Table<AppConfig>().ToList<AppConfig>();
int tCount = tApplicationConfig.Count;
AppConfigListBox.Items.Clear();
foreach (var t in tApplicationConfig)
{
AppConfigListBox.Items.Add(t);
}
}
C. 新增資料;
private void AddApplicationConfig()
{
try
{
AppConfig tConfig = new AppConfig
{
Id = Guid.NewGuid().ToString(),
ConfigKey = txtKey.Text,
ConfigValue = txtValue.Text
};
gDBConn.Insert(tConfig);
GetApplicationConfigData();
MessageBox.Show("新增資料成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
建立新物件,並加入其資料表中。
D. 修改資料;
private void AppConfigListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (AppConfigListBox.SelectedItem == null) return;
try
{
AppConfig tItem = AppConfigListBox.SelectedItem as AppConfig;
tItem.ConfigKey = "ChangeKey";
tItem.ConfigValue = "ChangeKey";
gDBConn.Update(tItem);
//GetApplicationConfigData();
MessageBox.Show("修改資料成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
如果您的資料表要做修改與刪除,要記得在宣告資料表時指定Primary Key才能正常使用,否則會出現Exception。
E. 刪除資料;
private void DeleteApplicationConfig()
{
try
{
AppConfig tItem = AppConfigListBox.SelectedItem as AppConfig;
gDBConn.Delete(tItem);
GetApplicationConfigData();
MessageBox.Show("刪除資料成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
如果您的資料表要做修改與刪除,要記得在宣告資料表時指定Primary Key才能正常使用,否則會出現Exception。
透過上述的範例可以得知,在操作SQLite資料庫裡的資料也是採用物件概念的操作方式,接近Entity framework的概念,
MS提供支援WP的SQL CE也是相同道理,詳細的說明可參考<Windows Phone 7 - Local Database概論 - 1>
與<Windows Phone 7 – Local Database概論 - 2>。
另外,如果您還是比較習慣使用SQL指令來操作的話,
可參考<A new SQLite wrapper for Windows Phone 8 and Windows 8 – The basics>。
》Copy database file to local folder on first startup:
如果您的應用程式XAP裡有內建的SQLite資料庫檔案,要記得在App第一次啟動時(Application_Launching),
就將該DB檔移動至Local Folder (IsolatedStorage)中。
為甚麼需要這樣做呢?道理在於XAP包裝的資料是被安裝於Install Folder,該資料夾是不可以寫入的,這樣一來也就無法操作資料了。
因此,可以透過下列的方式進行啟動時的檔案搬移:
private async void CopyDBFile()
{
StorageFile tFile = null;
String tFileName = "WPSqlite.db";
try
{
// 識別檔案是否存在
string tFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, tFileName);
tFile = await StorageFile.GetFileFromPathAsync(tFilePath);
}
catch (FileNotFoundException)
{
// 代表檔案不存在
if (tFile == null)
{
// 從installation folder 將檔案複製到 local folder
IsolatedStorageFile tIsoFile = IsolatedStorageFile.GetUserStoreForApplication();
// 建立一個Stream負責從installation folder將檔案讀出來
using (Stream tInput = Application.GetResourceStream(new Uri(tFileName, UriKind.Relative)).Stream)
{
// 建立IsolatedStorageFileStream負責寫入 local folder
using (IsolatedStorageFileStream tOutput = tIsoFile.CreateFile(tFileName))
{
byte[] tReadBuffer = new byte[4096];
int tBytesRead = -1;
while ((tBytesRead = tInput.Read(tReadBuffer, 0, tReadBuffer.Length)) > 0)
{
tOutput.Write(tReadBuffer, 0, tBytesRead);
}
}
}
}
}
}
透過檢查指定目錄下是否有檔案為依據,進行檔案的移動。
[範例程式]
======
以上是分享在WP8上使用SQLite的方式,在行動狀置上透過SQLite這種輕量型的DB蠻常見的,
但過去WP 7.1透過SQLCE要自行建立Data Context對於很多開發者沒有工具,能透過程式碼建立
真的蠻辛苦的, SQLCE也不能與其他平台共享資料,所以像我就很少使用它。但現在有人SQLite
的支援我相信會讓開發者更方便的操作。
References:
‧Precompiled Binaries for Windows Phone 8
‧Using SQLite in your Windows 8 Metro style applications
‧SQLite On WinRT, Metro, Windows 8 Mobile
‧Windows Phone 8 SQLite cross platform sample
‧How to use SQLite in Windows Phone (必讀)
‧Working with SQLite in Windows Phone 8: a sqlite-net version for mobile (重要)
‧peterhuene / sqlite-net-wp8 (必要元件)
‧Using SQLite with Windows Phone 8 apps (重要)
‧Windows (RT and Phone) and Sqlite (Part 1)
‧Windows (RT and Phone) and Sqlite (Part 2)
‧Windows (RT and Phone) and Sqlite (Part 3)
‧A new SQLite wrapper for Windows Phone 8 and Windows 8 – The basics (使用sql指令處理的範例)
‧Icon Explorer: 1000+ FREE Symbol Icons Organized in 25 categories