F#でSQLite
今回はF#でSQLiteを利用してみたいと思います。
System.Data.SQLite入手
NuGetで下記のパッケージを取得します。
データベース準備
sample.sqliteファイルに、下記のテーブルを定義しています。
作成は「DB Browser for SQLite」や、IDEに付属のツール、上記のdllを利用してプログラミング等で行えます。
personテーブル
id | INTEGER | PRIMARY KEY AUTOINCREMENT |
name | TEXT | |
age | INTEGER |
System.Data.SQLite単体で利用
生のSQL文を作成して実行しています。
望んだままのSQLを発行することが可能です。
DataSourceにはsample.sqliteのパスを指定してください。
let connectionString = SQLiteConnectionStringBuilder(DataSource = "sample.sqlite").ToString() use connection = new SQLiteConnection(connectionString) connection.Open() // レコード追加 using (connection.CreateCommand()) (fun command -> command.CommandText <- "INSERT INTO person (name, age) VALUES (@name, @age)" [ SQLiteParameter("@name", "Jerald") SQLiteParameter("@age", 40) ] |> List.iter (command.Parameters.Add >> ignore) command.ExecuteNonQuery() |> ignore ) // クエリ using (connection.CreateCommand()) (fun command -> command.CommandText <- "SELECT * FROM person WHERE 10 < age" use reader = command.ExecuteReader() while reader.Read() do printf "id:%A name:%A age:%A\n" reader.["id"] reader.["name"] reader.["age"] ) connection.Close()
LINQ to SQLを利用
SQL文の作成に、IQueryableを利用します。
これによりSQL文の間違いをコンパイル時に見つけやすくなります。
参照にSystem.Data.Linq.dll、System.Data.dll、System.Transactions.dllを追加してください。
AUTOINCREMENTを利用できるよう、IDはNullableで定義してあります。
[<Table>] type Person() = [<Column(IsPrimaryKey = true)>] member val ID = Nullable<int>() with get, set [<Column>] member val Name = "" with get, set [<Column>] member val Age = 0 with get, set let connectionString = SQLiteConnectionStringBuilder(DataSource = "sample.sqlite").ToString() use connection = new SQLiteConnection(connectionString) use context = new DataContext(connection) // レコード追加 context.GetTable<Person>().InsertOnSubmit(Person(Name = "Jerald", Age = 40)) context.SubmitChanges() // クエリ query { for person in context.GetTable<Person>() do where (10 < person.Age) } |> Seq.iter (fun x -> printf "id:%A name:%A age:%A\n" x.ID.Value x.Name x.Age)
SQLProvider利用
テーブルクラスの生成を、TypeProviderを利用して行うようにしてみます。
下記NuGetを取得します。
SqlDataProviderに、自動生成対象のデータベースのパスを指定します。
[<Literal>] let connectionStringCompileTime = "Data Source=sample.sqlite;Version=3" type Database = SqlDataProvider< DatabaseVendor = Common.DatabaseProviderTypes.SQLITE, ConnectionString = connectionStringCompileTime > let connectionString = SQLiteConnectionStringBuilder(DataSource = "sample.sqlite").ToString() let context = Database.GetDataContext(connectionString) // レコード追加 let person = context.Main.Person.Create() person.Name <- "Jerald" person.Age <- 40L context.SubmitUpdates() // クエリ query { for person in context.Main.Person do where (person.Age > 10L) // 10L < person.Age では動作しない… } |> Seq.iter (fun x -> printf "id:%A name:%A age:%A\n" x.Id x.Name x.Age)