FSharp.ORM


FSharp.ORM

Documentation

The FSharp.ORM library can be installed from NuGet:
PM> Install-Package FSharp.ORM

Example

This example demonstrates setting up a database connection and using it to insert, edit, query, and delete records.

Schema

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
create table Department (
    DepartmentId int primary key,
    DepartmentName varchar(50) unique,
    VersionNo int not null
);
create table Employee (
    EmployeeId int identity primary key,
    EmployeeName varchar(50),
    DepartmentId int FOREIGN KEY REFERENCES Department(DepartmentId),
    VersionNo int not null
);
 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
83: 
84: 
85: 
86: 
87: 
#r "FSharp.QueryProvider.dll"
#r "FSharp.ORM.dll"

open FSharp.ORM

open System
open FSharp.ORM

// define a module wraps Soma.Core.Db module
module MyDb = 
    let config = 
        { new MsSqlConfig() with
            member this.ConnectionString = "Data Source=localhost;Initial Catalog=FSharp.ORM.Tutorial;Integrated Security=True" }
    let query<'T> = Db.query<'T> config
    let queryOnDemand<'T> = Db.queryOnDemand<'T> config
    let queryable<'T when 'T : not struct> = Db.queryable<'T> config
    let queryableDirectSql<'T when 'T : not struct> = Db.queryableDirectSql<'T> config
    let queryableDelete<'T when 'T : not struct> : Linq.IQueryable<'T> -> unit = Db.queryableDelete<'T> config
    let execute sql expr = Db.execute config sql expr
    let find<'T when 'T : not struct> = Db.find<'T> config
    let tryFind<'T when 'T : not struct> = Db.tryFind<'T> config
    let insert<'T when 'T : not struct> = Db.insert<'T> config
    let update<'T when 'T : not struct> = Db.update<'T> config
    let delete<'T when 'T : not struct> = Db.delete<'T> config
    let call<'T when 'T : not struct> = Db.call<'T> config

type DepartmentId = int
// define a record mapped to a table 
type Department =
    { [<Id>]
      DepartmentId : DepartmentId
      DepartmentName : string
      [<Version>]
      VersionNo : int option }
let createDepartment id name =
    { DepartmentId = id
      DepartmentName = name
      VersionNo = None }

type Employee =
    { [<Id(IdKind.Identity)>]
      EmployeeId : int option
      EmployeeName : string option
      DepartmentId : DepartmentId option
      [<Version>]
      VersionNo : int option }

let salesDepartmentId = 1
// insert 
let salesDepartment = 
    createDepartment salesDepartmentId "Sales"
    |> MyDb.insert

// load
let salesDepartmentLoaded =
    query { for x in MyDb.queryable<Department> do
            where(x.DepartmentId = salesDepartmentId)
            exactlyOne }

// load with a partial string comparison
let searchDepartments =
    query { for x in MyDb.queryable<Department> do
            where(x.DepartmentName.Contains("Sa")) }

printfn "Search results: %A" (searchDepartments |> Seq.toList)

// update
let updatedSalesDepartment = MyDb.update { salesDepartment with DepartmentName = "Sales & Marketing" }

printfn "Updated record: %A" updatedSalesDepartment

// delete
MyDb.delete updatedSalesDepartment
printfn "Deleted record: %A" updatedSalesDepartment

// delete all records that would be returned by a linq query
MyDb.queryableDelete
    (query {
        for x in MyDb.queryable<Department> do
        where(x.DepartmentName.Contains("Sa")) })
 
// execute arbitrary SQL
let rows = 
    MyDb.execute @"
    delete from Employee 
    " []
printfn "Affected rows: %A" rows

Some more info

Samples & documentation

The library comes with comprehensible documentation. It can include tutorials automatically generated from *.fsx files in the content folder. The API reference is automatically generated from Markdown comments in the library implementation.

  • Tutorial contains a further explanation of this sample library.

  • API Reference contains automatically generated documentation for all types, modules and functions in the library. This includes additional brief samples on using most of the functions.

Contributing and copyright

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests. If you're adding a new public API, please also consider adding samples that can be turned into a documentation. You might also want to read the library design notes to understand how it works.

The library is available under Public Domain license, which allows modification and redistribution for both commercial and non-commercial purposes. For more information see the License file in the GitHub repository.

Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
namespace FSharp.ORM
namespace System
val config : MsSqlConfig

Full name: Index.MyDb.config
Multiple items
type MsSqlConfig =
  inherit DbConfigBase
  new : unit -> MsSqlConfig
  override QueryTranslator : QueryType -> IDbConnection -> Expression -> IDbCommand * ConstructionInfo option
  override Dialect : IDialect

Full name: FSharp.ORM.MsSqlConfig

--------------------
new : unit -> MsSqlConfig
val this : MsSqlConfig
property DbConfigBase.ConnectionString: string
val query<'T> : (string -> (string * obj * Type) list -> 'T list)

Full name: Index.MyDb.query
Multiple items
module Db

from FSharp.ORM

--------------------
type Db =
  interface IDb
  new : config:IDbConfig -> Db
  abstract member Call : procedure:'T -> unit (requires reference type)
  abstract member Delete : entity:'T * opt:DeleteOpt -> unit (requires reference type)
  abstract member Delete : entity:'T -> unit (requires reference type)
  abstract member Execute : sql:string * condition:obj -> int
  abstract member Execute : sql:string -> int
  abstract member ExecuteReader : handler:Func<DbDataReader,'T> * sql:string * condition:obj -> 'T
  abstract member ExecuteReader : handler:Func<DbDataReader,'T> * sql:string -> 'T
  abstract member Find : id:obj -> 'T (requires reference type and default constructor)
  ...

Full name: FSharp.ORM.Db

--------------------
new : config:IDbConfig -> Db
val query : config:IDbConfig -> sql:string -> condition:(string * obj * Type) list -> 'T list

Full name: FSharp.ORM.Db.query
val queryOnDemand<'T> : (string -> (string * obj * Type) list -> seq<'T>)

Full name: Index.MyDb.queryOnDemand
val queryOnDemand : config:IDbConfig -> sql:string -> condition:(string * obj * Type) list -> seq<'T>

Full name: FSharp.ORM.Db.queryOnDemand
val queryable<'T (requires reference type)> : Linq.IQueryable<'T> (requires reference type)

Full name: Index.MyDb.queryable
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
val queryable : config:IDbConfig -> Linq.IQueryable<'T> (requires reference type)

Full name: FSharp.ORM.Db.queryable
val queryableDirectSql<'T (requires reference type)> : (seq<Sql> -> seq<Parameter> -> Linq.IQueryable<'T>) (requires reference type)

Full name: Index.MyDb.queryableDirectSql
val queryableDirectSql : config:IDbConfig -> query:seq<Sql> -> parametters:seq<Parameter> -> Linq.IQueryable<'T> (requires reference type)

Full name: FSharp.ORM.Db.queryableDirectSql
val queryableDelete<'T (requires reference type)> : (Linq.IQueryable<'T> -> unit) (requires reference type)

Full name: Index.MyDb.queryableDelete
Multiple items
namespace System.Linq

--------------------
namespace Microsoft.FSharp.Linq
Multiple items
type IQueryable =
  member ElementType : Type
  member Expression : Expression
  member Provider : IQueryProvider

Full name: System.Linq.IQueryable

--------------------
type IQueryable<'T> =

Full name: System.Linq.IQueryable<_>
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val queryableDelete : config:IDbConfig -> query:Linq.IQueryable<'T> -> unit (requires reference type)

Full name: FSharp.ORM.Db.queryableDelete
val execute : sql:string -> expr:(string * obj * Type) list -> int

Full name: Index.MyDb.execute
val sql : string
val expr : (string * obj * Type) list
val execute : config:IDbConfig -> sql:string -> condition:(string * obj * Type) list -> int

Full name: FSharp.ORM.Db.execute
val find<'T (requires reference type)> : (obj list -> 'T) (requires reference type)

Full name: Index.MyDb.find
val find : config:IDbConfig -> id:obj list -> 'T (requires reference type)

Full name: FSharp.ORM.Db.find
val tryFind<'T (requires reference type)> : (obj list -> 'T option) (requires reference type)

Full name: Index.MyDb.tryFind
val tryFind : config:IDbConfig -> id:obj list -> 'T option (requires reference type)

Full name: FSharp.ORM.Db.tryFind
val insert<'T (requires reference type)> : ('T -> 'T) (requires reference type)

Full name: Index.MyDb.insert
val insert : config:IDbConfig -> entity:'T -> 'T (requires reference type)

Full name: FSharp.ORM.Db.insert
val update<'T (requires reference type)> : ('T -> 'T) (requires reference type)

Full name: Index.MyDb.update
val update : config:IDbConfig -> entity:'T -> 'T (requires reference type)

Full name: FSharp.ORM.Db.update
val delete<'T (requires reference type)> : ('T -> unit) (requires reference type)

Full name: Index.MyDb.delete
val delete : config:IDbConfig -> entity:'T -> unit (requires reference type)

Full name: FSharp.ORM.Db.delete
val call<'T (requires reference type)> : ('T -> 'T) (requires reference type)

Full name: Index.MyDb.call
val call : config:IDbConfig -> procedure:'T -> 'T (requires reference type)

Full name: FSharp.ORM.Db.call
type DepartmentId = int

Full name: Index.DepartmentId
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
type Department =
  {DepartmentId: DepartmentId;
   DepartmentName: string;
   VersionNo: int option;}

Full name: Index.Department
Multiple items
type IdAttribute =
  inherit Attribute
  new : unit -> IdAttribute
  new : IdKind -> IdAttribute
  member Kind : IdKind

Full name: FSharp.ORM.IdAttribute

--------------------
new : unit -> IdAttribute
new : IdKind -> IdAttribute
Multiple items
Department.DepartmentId: DepartmentId

--------------------
type DepartmentId = int

Full name: Index.DepartmentId
Department.DepartmentName: string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
Multiple items
type Version =
  new : unit -> Version + 4 overloads
  member Build : int
  member Clone : unit -> obj
  member CompareTo : version:obj -> int + 1 overload
  member Equals : obj:obj -> bool + 1 overload
  member GetHashCode : unit -> int
  member Major : int
  member MajorRevision : int16
  member Minor : int
  member MinorRevision : int16
  ...

Full name: System.Version

--------------------
type VersionAttribute =
  inherit Attribute
  new : unit -> VersionAttribute
  new : VersionKind -> VersionAttribute
  member Kind : VersionKind

Full name: FSharp.ORM.VersionAttribute

--------------------
Version() : unit
Version(version: string) : unit
Version(major: int, minor: int) : unit
Version(major: int, minor: int, build: int) : unit
Version(major: int, minor: int, build: int, revision: int) : unit

--------------------
new : unit -> VersionAttribute
new : VersionKind -> VersionAttribute
Department.VersionNo: int option
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
val createDepartment : id:DepartmentId -> name:string -> Department

Full name: Index.createDepartment
val id : DepartmentId
val name : string
union case Option.None: Option<'T>
type Employee =
  {EmployeeId: int option;
   EmployeeName: string option;
   DepartmentId: DepartmentId option;
   VersionNo: int option;}

Full name: Index.Employee
type IdKind =
  | Assigned = 0
  | Identity = 1
  | Sequence = 2

Full name: FSharp.ORM.IdKind
IdKind.Identity: IdKind = 1
Employee.EmployeeId: int option
Employee.EmployeeName: string option
Multiple items
Employee.DepartmentId: DepartmentId option

--------------------
type DepartmentId = int

Full name: Index.DepartmentId
Employee.VersionNo: int option
val salesDepartmentId : int

Full name: Index.salesDepartmentId
val salesDepartment : Department

Full name: Index.salesDepartment
module MyDb

from Index
val salesDepartmentLoaded : Department

Full name: Index.salesDepartmentLoaded
val query : Linq.QueryBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.query
val x : Department
custom operation: where (bool)

Calls Linq.QueryBuilder.Where
Department.DepartmentId: DepartmentId
custom operation: exactlyOne

Calls Linq.QueryBuilder.ExactlyOne
val searchDepartments : Linq.IQueryable<Department>

Full name: Index.searchDepartments
String.Contains(value: string) : bool
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
module Seq

from Microsoft.FSharp.Collections
val toList : source:seq<'T> -> 'T list

Full name: Microsoft.FSharp.Collections.Seq.toList
val updatedSalesDepartment : Department

Full name: Index.updatedSalesDepartment
val rows : int

Full name: Index.rows
Fork me on GitHub