Xamarin.FormsでSQLiteを使う
Xamarin.FormsでSQLiteを使用するには、
専用のパッケージはもちろん必要になるのですが、
Xamarin.Formsは各プラットーフォームに指示を送る司令塔の様な役割のため、
Xamarin.Forms自体がデータベースの実ファイルを持つわけではありません。
なので、Xamarin.FormsでSQLiteを使用するには、
各プラットフォームからデータベースへのパスを渡してあげる必要があります。
※ここではSqliteSampleというソリューションを作成しました。
MainActivity.cs
using Android.App;
using Android.Content.PM;
using Android.OS;
namespace SqliteSample.Droid
{
[Activity(Label = "SqliteSample.Droid", Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
//指定したファイルのパスを取得します。
var dbPath = GetLocalFilePath("sqlitetest.db3");
//この段階ではまだエラーになります。
LoadApplication(new App(dbPath));
}
public static string GetLocalFilePath(string filename)
{
//指定されたファイルのパスを取得します。なければ作成してそのパスを返却します
var path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
return System.IO.Path.Combine(path, filename);
}
}
}
AppDelegate.cs
using System;
using Foundation;
using UIKit;
namespace SqliteSample.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
//指定したファイルのパスを取得します。
var dbPath = GetLocalFilePath("culculate.db3");
//この段階ではまだエラーになります。
LoadApplication(new App(dbPath));
return base.FinishedLaunching(app, options);
}
public static string GetLocalFilePath(string filename)
{
//指定されたファイルのパスを取得します。なければ作成してそのパスを返却します
var docFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var libFolder = System.IO.Path.Combine(docFolder, "..", "Library", "Databases");
if (!System.IO.Directory.Exists(libFolder)) {
System.IO.Directory.CreateDirectory(libFolder);
}
return System.IO.Path.Combine(libFolder, filename);
}
}
}
Xamarin.Forms
App.xaml.cs
using Xamarin.Forms;
namespace SqliteSample
{
public partial class App : Application
{
//データベースのパスを格納
public static string dbPath;
//コンストラクタの引数にstring型の引数を追加
public App(string dbPath)
{
//AppのdbPathに引数のパスを設定します
App.dbPath = dbPath;
InitializeComponent();
MainPage = new SqliteSamplePage();
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
※ここではAppクラスのコンストラクタの引数を変更して、データベースのパスを渡していますが、
DependencyServiceクラスを使用する方法でも問題ありません(むしろそちらの方が良いと思います)。
次にXamarin.Forms及び各プラットーフォームのプロジェクトへ
SQLite-net PCLパッケージを追加します。
現在(2017年3月5日時点)、SQLite-net PCLの最新バージョンは、
1.3.1ですが、このバージョンを追加しようとするとエラーになるため、
1.2.1を選択してください。
または、Xamarin.Formsのプロジェクトオプションを開き、
ビルド > 全般 の.Net Portable をPCL 4.5 - Profile259 に変更します。
さらに、iOSプロジェクトで使用する場合は、
iOSのプロジェクトオプションを開き、
ビルド > iOS Build のリンカーの動作をフレームワーク SDK のみをリンクするを
選択します。
これでSQLiteを使うための準備が整いました。
実際の使用方法の例です。
まず、今回の例ではidと名前だけを格納するテーブルUserを作ります。
UserModelというクラスを作成し、そのクラスにテーブル構造を定義し、
さらにインサート・セレクトを行うメソッドを用意します。
UserModel.cs
using System;
using System.Collections.Generic;
using SQLite;
namespace SqliteSample
{
//テーブル名を指定
[Table("User")]
public class UserModel
{
//プライマリキー 自動採番されます
[PrimaryKey, AutoIncrement, Column("_id")]
//idカラム
public int Id { get; set; }
//名前カラム
public string Name { get; set; }
//Userテーブルに行追加するためのメソッドです
public static void insertUser(string name)
{
//データベースに接続します
using (SQLiteConnection db = new SQLiteConnection(App.dbPath)) {
try {
//データベースにUserテールブを作成します
db.CreateTable();
//Userテーブルに行追加します
db.Insert(new UserModel() { Name = name });
db.Commit();
} catch (Exception e) {
db.Rollback();
System.Diagnostics.Debug.WriteLine(e);
}
}
}
//Userテーブルの行データを取得します
public static List selectUser()
{
using (SQLiteConnection db = new SQLiteConnection(App.dbPath)) {
try {
//データベースに指定したSQLを発行します
return db.Query("SELECT * FROM [User] ");
} catch (Exception e) {
System.Diagnostics.Debug.WriteLine(e);
return null;
}
}
}
}
}
SqliteSamplePage.xaml.cs
using Xamarin.Forms;
namespace SqliteSample
{
public partial class SqliteSamplePage : ContentPage
{
public SqliteSamplePage()
{
InitializeComponent();
var layout = new StackLayout { HorizontalOptions = LayoutOptions.Center, Margin = new Thickness { Top = 100 } };
//Userテーブルに適当なデータを追加
UserModel.insertUser("鈴木");
UserModel.insertUser("田中");
UserModel.insertUser("斎藤");
//Userテーブルの行データを取得
var query = UserModel.selectUser();
foreach (var user in query) {
//Userテーブルの名前列をLabelに書き出します
layout.Children.Add(new Label { Text = user.Name });
}
Content = layout;
}
}
}
これで実行すると下の画像のようにテーブルに格納したデータが表示されます