Microsoft.Data.Sqlite は、Xamarin で SQLite を使うときの定番になっている sqlite-net-pcl と同じく、SQLitePCL.raw に依存している。 sqlite-net-pcl が Xamarin.iOS で利用できるということは、Microsoft.Data.Sqlite も利用できるに違いない。
サンプルを書いて試してみた。
using System; using System.Collections.Generic; using System.IO; using Foundation; using Microsoft.Data.Sqlite; using UIKit; using Xamarin.Essentials; namespace HelloSqlite { public class Application { static void Main(string[] args) { UIApplication.Main(args, null, "AppDelegate"); } } [Register("AppDelegate")] public class AppDelegate : UIApplicationDelegate { public override UIWindow Window { get; set; } public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) { SQLitePCL.Batteries_V2.Init(); Window = new UIWindow(UIScreen.MainScreen.Bounds); Window.RootViewController = new UINavigationController( new ItemsViewController()); Window.MakeKeyAndVisible(); return true; } } public class Item { public int Id { get; set; } public string Content { get; set; } } public class ItemsViewController : UITableViewController { List<Item> items = new List<Item>(); public ItemsViewController() : base(UITableViewStyle.Plain) { Title = "HelloSqlite"; } public override void ViewDidLoad() { base.ViewDidLoad(); NavigationItem.RightBarButtonItem = new UIBarButtonItem( UIBarButtonSystemItem.Add, HandleAdd); CreateTable(); LoadItems(); } public override nint RowsInSection(UITableView tableView, nint section) { return items.Count; } public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) { const string cellId = "ItemCell"; var cell = tableView.DequeueReusableCell(cellId) ?? new UITableViewCell(UITableViewCellStyle.Default, cellId); var item = items[indexPath.Row]; cell.TextLabel.Text = item.Content; return cell; } void HandleAdd(object sender, EventArgs e) { AddItem(); LoadItems(); } void CreateTable() { using (var connection = CreateConnection()) { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandText = @" CREATE TABLE IF NOT EXISTS items ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL );"; command.ExecuteNonQuery(); } } } void AddItem() { using (var connection = CreateConnection()) { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandText = $@" INSERT INTO items ( content ) VALUES ( '{DateTime.Now}' )"; command.ExecuteNonQuery(); } } } void LoadItems() { var nextItems = new List<Item>(); using (var connection = CreateConnection()) { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandText = @" SELECT id, content FROM items ORDER BY id"; using (var reader = command.ExecuteReader()) { while (reader.Read()) { var item = new Item { Id = reader.GetInt32(0), Content = reader.GetString(1), }; nextItems.Add(item); } } } } items = nextItems; TableView.ReloadData(); } SqliteConnection CreateConnection() { var builder = new SqliteConnectionStringBuilder(); builder.DataSource = Path.Combine( FileSystem.AppDataDirectory, "HelloSqlite.db"); return new SqliteConnection(builder.ToString()); } } }
iOS のシミュレーターだと動的コード生成を行うプログラムであっても動かせてしまうので、実機で動くことを確認するまでは安心できない。
このサンプルを実機に転送して実行したところ、期待通り SQLite データベースにデータを登録できた。
Microsoft.Data.Sqlite が使えたということは、 ADO.NET の抽象化の上に構築されたライブラリが Xamarin.iOS でも使える、 ということになる。 ただし、動的コード生成を行っていなければね。 このあいだ Dapper のソースコードを読んだら DynamicMethod 使っていたんだよなぁ。 残念。