Databases and Data Access
Dapper (+ Dapper.FSharp) Micro-ORM: SQL with object mapping; Dapper.FSharp adds a CE-based query DSL Functional ADO.NET wrapper
Type-safe query builders generated from your schema Type provider for many databases Compile-time checked SQL for SQL Server
Entity Framework Core (+ EFCore.FSharp) PostgreSQL-friendly functional API PostgreSQL document DB and event store
LiteDB, MongoDB.Driver, StackExchange.Redis DbUp, Evolve, Grate
// Dapper (micro-ORM) with records
#r "nuget: Dapper"
#r "nuget: Microsoft.Data.Sqlite"
open Dapper
open Microsoft.Data.Sqlite
[<CLIMutable>]
type User = { Id: int64; Name: string; Email: string }
let connStr = "Data Source=app.db"
let createTable () =
use conn = new SqliteConnection(connStr)
conn.Execute("CREATE TABLE IF NOT EXISTS Users (Id INTEGER PRIMARY KEY, Name TEXT, Email TEXT)") |> ignore
let insertUser (name: string) (email: string) =
use conn = new SqliteConnection(connStr)
conn.Execute("INSERT INTO Users (Name, Email) VALUES (@Name, @Email)", {| Name = name; Email = email |}) // parameterized
let getUsers () =
use conn = new SqliteConnection(connStr)
conn.Query<User>("SELECT Id, Name, Email FROM Users WHERE Name LIKE @Pattern", {| Pattern = "A%" |}) |> List.ofSeq
let getUserAsync (id: int64) = task {
use conn = new SqliteConnection(connStr)
let! users = conn.QueryAsync<User>("SELECT * FROM Users WHERE Id = @Id", {| Id = id |})
return Seq.tryHead users
}