SQLProvider

CRUD sample

open System


let ctx = sql.GetDataContext()

let orders = ctx.Main.Orders
let employees = ctx.Main.Employees

let customer = ctx.Main.Customers |> Seq.head
let employee = ctx.Main.Employees |> Seq.head
let now = DateTime.Now

Create() has various overloads to make inserting records simple.

Prefer the typed ``Create(...)``: its name lists the required columns (not nullable, not generated, sorted by name), so adding a required column to the table breaks the build where rows are created instead of failing at runtime. Set the optional columns afterwards. Call it with the backticked name, so two arguments of the same type can't swap places unnoticed when the column list changes.

let emp = ctx.Main.Employees.``Create(FirstName, LastName)``("Don", "Syme")

Optional columns are set on the returned row, e.g. emp.Title <- "Founder" (or ValueSome "Founder" with UseOptionTypes = NullableColumnType.VALUE_OPTION). A key the application generates, like a UUID, is set the same way: row.Id <- Guid.CreateVersion7().

The untyped Create() with property sets is for when you build rows dynamically. It compiles even when a required column is left out:

let row = orders.Create()
row.CustomerId <- customer.CustomerId
row.EmployeeId <- employee.EmployeeId
row.Freight <- 10M
row.OrderDate <- now.AddDays(-1.0)
row.RequiredDate <- now.AddDays(1.0)
row.ShipAddress <- "10 Downing St"
row.ShipCity <- "London"
row.ShipName <- "Dragons den"
row.ShipPostalCode <- "SW1A 2AA"
row.ShipRegion <- "UK"
row.ShippedDate <- now

Submit updates to the database

ctx.SubmitUpdates()

After updating, your item (row) will have the Id property.

To update a row without reading it first, create an entity with its key, set the columns, and mark only those columns as modified:

let update = ctx.Main.Orders.Create()
update.OrderId <- orderId
update.ShipCity <- "Leeds"
update._State <- Common.EntityState.Modified [ "ShipCity" ]
ctx.SubmitUpdates()

Delete the row

row.Delete()

Submit updates to the database

ctx.SubmitUpdates()

Insert a list of records:

type Employee = {
    FirstName:string
    LastName:string
}

let mvps1 = [
    {FirstName="Andrew"; LastName="Kennedy"};
    {FirstName="Mads"; LastName="Torgersen"};
    {FirstName="Martin";LastName="Odersky"};
]

mvps1
    |> List.map (fun x ->
                    let row = employees.Create()
                    row.FirstName <- x.FirstName
                    row.LastName <- x.LastName)

ctx.SubmitUpdates()

Or directly specify the fields:

let mvps2 = [
    {FirstName="Byron"; LastName="Cook"};
    {FirstName="James"; LastName="Huddleston"};
    {FirstName="Xavier";LastName="Leroy"};
]

mvps2
    |> List.map (fun x ->
                   employees.Create(x.FirstName, x.LastName)
                    )

ctx.SubmitUpdates()

update a single row assuming Id is unique

type Employee2 = {
    Id:int64
    FirstName:string
    LastName:string
}

let updateEmployee (employee: Employee2) =
    let foundEmployeeMaybe = query {
        for p in ctx.Main.Employees do
        where (p.EmployeeId = employee.Id)
        select (Some p)
        exactlyOneOrDefault
    }
    match foundEmployeeMaybe with
    | Some foundEmployee ->
        foundEmployee.FirstName <- employee.FirstName
        foundEmployee.LastName <- employee.LastName
        ctx.SubmitUpdates()
    | None -> ()

let updateEmployee' (employee: Employee2) =
    query {
        for p in ctx.Main.Employees do
        where (p.EmployeeId = employee.Id)
    }
    |> Seq.iter( fun e ->
        e.FirstName <- employee.FirstName
        e.LastName <- employee.LastName
    )
    ctx.SubmitUpdates()

let john = {
  Id = 1L
  FirstName = "John"
  LastName = "Doe" }

updateEmployee john
updateEmployee' john

Finally it is also possible to specify a seq of string * obj, which is precisely the output of .ColumnValues:

employees
    |> Seq.map (fun x ->
                ctx.Main.Employees.Create(x.ColumnValues)) // create twins
    |>  Seq.toList

/// Retrieve the FSharp.Data.Sql.Common.SqlEntity objects
let twins = ctx.GetUpdates()

ctx.ClearUpdates() // delete the updates
ctx.GetUpdates() // Get the updates
ctx.SubmitUpdates() // no record is added

Transactions and isolation level

SubmitUpdates / SubmitUpdatesAsync wrap the write in a TransactionScope created with TransactionScopeOption.Required: it joins an ambient transaction if one already exists, otherwise it starts a new one. Only the submit is wrapped — your queries/reads are not put in a transaction, so reads carry no locking overhead.

Because of Required, the way to make a read-then-write atomic (read some rows, decide, then write) is to open your own transaction around both the reads and the SubmitUpdates, and that scope's isolation level is the one that applies:

open System.Transactions

use scope =
    new TransactionScope(
        TransactionScopeOption.Required,
        TransactionOptions(IsolationLevel = IsolationLevel.ReadCommitted),
        TransactionScopeAsyncFlowOption.Enabled)   // needed if you await inside the scope

// Open a FRESH data context *inside* the scope for this unit of work (see note below):
let ctx = sql.GetDataContext connstr

// ... your queries (reads) ...
// ... your Create()/mutations ...
ctx.SubmitUpdates()
scope.Complete()

Create a fresh context per transaction — don't reuse a shared/long-lived one. A data context accumulates all pending changes (every Create(), Delete(), and column edit) until SubmitUpdates() flushes them to the database together. If you'd reuse a long-lived or shared context, a SubmitUpdates() inside your transaction could commit unrelated pending changes that another request or user left sitting on that context. Opening a new context inside the scope keeps each transaction small and self-contained, and guarantees the tracked changes are exactly what this transaction should write — and it keeps the context's connection enlisted in this transaction.

Reads are different — a shared context is fine (and fastest). The "fresh context per unit of work" rule above is about writes. If you use .GetReadOnlyDataContext connstr you can enforce read-only: it has no pending-change nor transaction concerns. For read-only operations you can safely share/cache one database context across requests, which is actually the fastest way to read (no per-call context setup). The one thing to add is resilience: if the connection dies for reasons outside SQLProvider (driver/network/timeout), you need logic to rebuild the shared context — e.g. hold it in a mutable Lazy and recreate it when the value is null or a call throws a connection error.

Isolation level gotcha: SQLProvider's TransactionOptions.Default — used only when SubmitUpdates has to create a standalone write transaction (no ambient scope) — inherits the .NET default, which is Serializable, not ReadCommitted. A bare new TransactionScope() is the same: it also defaults to Serializable. So if you want ReadCommitted (usually the right choice to avoid over-locking on a larger system), pass it explicitly through TransactionOptions, as above. Choosing the isolation level for a unit of work is intentionally the caller's job, not SQLProvider's (see issue #238 for one real-world use-case solution).

If your transaction spans an await / async continuation, remember TransactionScopeAsyncFlowOption.Enabled (otherwise the ambient transaction won't flow to the continuation thread — see the async page for a full example).

Read vs write contexts: SQLProvider can generate a read-only data context via GetReadOnlyDataContext() alongside the writable GetDataContext(), giving you compile-time separation of read and write code paths (the read-only context can't accidentally mutate/submit). They are type-level different. If you have a method parameter and you want to share a read-only query with a read that must run inside a write transaction, call .AsReadOnly() on the writable context to reuse its connection.

SQLProvider also supports async database operations:

ctx.SubmitUpdatesAsync() // |> Async.AwaitTask

OnConflict

The SQLite, PostgreSQL 9.5+ and MySQL 8.0+ providers support conflict resolution for INSERT statements.

They allow the user to specify if a unique constraint violation should be solved by ignoring the statement (DO NOTHING) or updating existing rows (DO UPDATE).

You can leverage this feature by setting the OnConflict property on a row object: * Setting it to DoNothing will add the DO NOTHING clause (PostgreSQL) or the OR IGNORE clause (SQLite). * Setting it to Update will add a DO UPDATE clause on the primary key constraint for all columns (PostgreSQL) or a OR REPLACE clause (SQLite).

Sql Server has a similar feature in the form of the MERGE statement. This is not yet supported.

let jane = ctx.Main.Employees.Create()
jane.EmployeeId <- 1L
jane.FirstName <- "Jane"
jane.LastName <- "Doe"

jane.OnConflict <- FSharp.Data.Sql.Common.OnConflict.Update

ctx.SubmitUpdates()

Delete-query for multiple items

To delete many items from a database table, DELETE FROM [dbo].[EMPLOYEES] WHERE (...), there is a way, although we don't recommend deleting items from a database. Instead, you should consider a deletion-flag column. You should also back up your database before trying this. Note that changes are immediately saved to the database even if you don't call ctx.SubmitUpdates().

Selecting which Create() to use

There are 3 overrides of create.

The ideal one to use is the long one ``Create(...)``(...):

let don = ctx.Main.Employees.``Create(FirstName, LastName)``("Don", "Syme")

This is because it will fail if your database structure changes. So, when your table gets new columns, the code will fail at compile time. Then you decide what to do with the new columns, and not let a bug to customers.

But you may want to use the plain .Create() if your setup is not optimal. Try to avoid these conditions:

In the last case you'll be maintaining code like this:

[<Literal>]
let employeeId = 123
// Got some untyped array of data from the client
let createSomeItem (data: seq<string*obj>)  =
    data
    |> Seq.map( // Some parsing and validation:
        function
        // Skip some fields
        | "EmployeeId", x
        | "PermissionLevel", x -> "", x
        // Convert and validate some fields
        | "PostalCode", x ->
            "PostalCode", x.ToString().ToUpper().Replace(" ", "") |> box
        | "BirthDate", x ->
            let bdate = x.ToString() |> DateTime.Parse
            if bdate.AddYears(18) > DateTime.UtcNow then
                failwith "Too young!"
            else
                "BirthDate", bdate.ToString("yyyy-MM-dd") |> box
        | others -> others)
    |> Seq.filter (fun (key,_) -> key <> "")
                  // Add some fields:
    |> Seq.append [|"EmployeeId", employeeId |> box;
                    "Country", "UK" |> box |]
    |> ctx.Main.Employees.Create

What to do if your creation fails systematically every time

Some underlying database connection libraries have problems with serializing underlying data types. So, if this fails:

emp.BirthDate <- DateTime.UtcNow
ctx.SubmitUpdates()

Try using .SetColumn("ColumnName", value |> box) for example:

emp.SetColumn("BirthDate", DateTime.UtcNow.ToString("yyyy-MM-dd HH\:mm\:ss") |> box)
ctx.SubmitUpdates()

SetColumn takes an object, giving you more control over the type serialization.

Identifying columns dynamically

let setIfExists columnName =
   if emp.HasColumn(columnName, StringComparison.InvariantCultureIgnoreCase) then
      emp.SetColumn(columnName, "testValue")
Multiple items
type LiteralAttribute = inherit Attribute new: unit -> LiteralAttribute

--------------------
new: unit -> LiteralAttribute
val resolutionPath: string = "C:\git\SQLProvider\docs\content\core/../../files/sqlite"
val connectionString: string = "Data Source=C:\git\SQLProvider\docs\content\core\..\northwindEF.db;Version=3;Read Only=false;FailIfMissing=True;"
Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Data

--------------------
namespace Microsoft.FSharp.Data
namespace FSharp.Data.Sql
type sql = SqlDataProvider<...>
type SqlDataProvider
<summary>Typed representation of a database</summary> <param name='ConnectionString'>The connection string for the SQL database</param> <param name='ConnectionStringName'>The connection string name to select from a configuration file</param> <param name='DatabaseVendor'> The target database vendor</param> <param name='IndividualsAmount'>The amount of sample entities to project into the type system for each SQL entity type. Default 50. Note GDPR/PII regulations if using individuals with ContextSchemaPath.</param> <param name='UseOptionTypes'>If set, F# option types will be used in place of nullable database columns. If not, you will always receive the default value of the column's type even if it is null in the database.</param> <param name='ResolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types. Types used in design-time: If no better clue, prefer .NET Standard 2.0 versions. Semicolon to separate multiple.</param> <param name='Owner'>Oracle: The owner of the schema for this provider to resolve. PostgreSQL: A list of schemas to resolve, separated by spaces, newlines, commas, or semicolons.</param> <param name='CaseSensitivityChange'>Should we do ToUpper or ToLower when generating table names?</param> <param name='TableNames'>Comma separated table names list to limit a number of tables in big instances. The names can have '%' sign to handle it as in the 'LIKE' query (Oracle and MSSQL Only)</param> <param name='ContextSchemaPath'>The location of the context schema previously saved with SaveContextSchema. When not empty, will be used to populate the database schema instead of retrieving it from then database.</param> <param name='OdbcQuote'>Odbc quote characters: Quote characters for the table and column names: `alias`, [alias]</param> <param name='SQLiteLibrary'>Use System.Data.SQLite or Mono.Data.SQLite or select automatically (SQLite only)</param> <param name='SsdtPath'>A path to an SSDT .dacpac file.'</param>
namespace FSharp.Data.Sql.Common
type DatabaseProviderTypes = | MSSQLSERVER = 0 | SQLITE = 1 | POSTGRESQL = 2 | MYSQL = 3 | ORACLE = 4 | MSACCESS = 5 | ODBC = 6 | FIREBIRD = 7 | MSSQLSERVER_DYNAMIC = 8 | MSSQLSERVER_SSDT = 9 | DUCKDB = 10 | EXTERNAL = 11
<summary> Specifies the database provider type for the SQL type provider. Each provider has its own specific implementation for SQL generation and data type mapping. </summary>
Common.DatabaseProviderTypes.SQLITE: Common.DatabaseProviderTypes = 1
<summary> SQLite database using System.Data.SQLite or Microsoft.Data.Sqlite </summary>
type SQLiteLibrary = | SystemDataSQLite = 0 | MonoDataSQLite = 1 | AutoSelect = 2 | MicrosoftDataSqlite = 3
<summary> Specifies which SQLite library to use for connections. Different libraries may have different capabilities and platform support. </summary>
Common.SQLiteLibrary.SystemDataSQLite: Common.SQLiteLibrary = 0
<summary> .NET Framework default </summary>
type CaseSensitivityChange = | ORIGINAL = 0 | TOUPPER = 1 | TOLOWER = 2
<summary> Specifies how to handle case sensitivity when generating table and column names. </summary>
Common.CaseSensitivityChange.ORIGINAL: Common.CaseSensitivityChange = 0
<summary> Keep original casing from the database </summary>
namespace System
val ctx: SqlDataProvider<...>.dataContext
SqlDataProvider<...>.GetDataContext() : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(selectOperations: SelectOperations) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='selectOperations'>Execute select-clause operations in SQL database rather than .NET-side.</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(commandTimeout: int) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='commandTimeout'>SQL command timeout. Maximum time for single SQL-command in seconds.</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(connectionString: string) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='connectionString'>The database runtime connection string</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(connectionString: string, selectOperations: SelectOperations) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='connectionString'>The database runtime connection string</param><param name='selectOperations'>Execute select-clause operations in SQL database rather than .NET-side.</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(transactionOptions: Transactions.TransactionOptions, commandTimeout: int) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param><param name='commandTimeout'>SQL command timeout. Maximum time for single SQL-command in seconds.</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(connectionString: string, commandTimeout: int) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='connectionString'>The database runtime connection string</param><param name='commandTimeout'>SQL command timeout. Maximum time for single SQL-command in seconds.</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(connectionString: string, transactionOptions: Transactions.TransactionOptions) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='connectionString'>The database runtime connection string</param><param name='transactionOptions'>TransactionOptions for the transaction created on SubmitChanges.</param>
   (+0 other overloads)
SqlDataProvider<...>.GetDataContext(connectionString: string, resolutionPath: string) : SqlDataProvider<...>.dataContext
<summary>Returns an instance of the SQL Provider using the static parameters</summary><param name='connectionString'>The database runtime connection string</param><param name='resolutionPath'>The location to look for dynamically loaded assemblies containing database vendor specific connections and custom types. Types used in design-time: If no better clue, prefer .NET Standard 2.0 versions. Semicolon to separate multiple.</param>
   (+0 other overloads)
val orders: SqlDataProvider<...>.dataContext.mainSchema.main.Orders
property SqlDataProvider<...>.dataContext.Main: SqlDataProvider<...>.dataContext.mainSchema with get
property SqlDataProvider<...>.dataContext.mainSchema.Orders: SqlDataProvider<...>.dataContext.mainSchema.main.Orders with get
<summary> The table Orders belonging to schema main</summary>
val employees: SqlDataProvider<...>.dataContext.mainSchema.main.Employees
property SqlDataProvider<...>.dataContext.mainSchema.Employees: SqlDataProvider<...>.dataContext.mainSchema.main.Employees with get
<summary> The table Employees belonging to schema main</summary>
val customer: SqlDataProvider<...>.dataContext.main.CustomersEntity
property SqlDataProvider<...>.dataContext.mainSchema.Customers: SqlDataProvider<...>.dataContext.mainSchema.main.Customers with get
<summary> The table Customers belonging to schema main</summary>
Multiple items
module Seq from FSharp.Data.Sql

--------------------
module Seq from Microsoft.FSharp.Collections
val head: source: 'T seq -> 'T
val employee: SqlDataProvider<...>.dataContext.main.EmployeesEntity
val now: DateTime
Multiple items
type DateTime = new: date: DateOnly * time: TimeOnly -> unit + 16 overloads member Add: value: TimeSpan -> DateTime member AddDays: value: float -> DateTime member AddHours: value: float -> DateTime member AddMicroseconds: value: float -> DateTime member AddMilliseconds: value: float -> DateTime member AddMinutes: value: float -> DateTime member AddMonths: months: int -> DateTime member AddSeconds: value: float -> DateTime member AddTicks: value: int64 -> DateTime ...
<summary>Represents an instant in time, typically expressed as a date and time of day.</summary>

--------------------
DateTime ()
   (+0 other overloads)
DateTime(ticks: int64) : DateTime
   (+0 other overloads)
DateTime(date: DateOnly, time: TimeOnly) : DateTime
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(date: DateOnly, time: TimeOnly, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : DateTime
   (+0 other overloads)
property DateTime.Now: DateTime with get
<summary>Gets a <see cref="T:System.DateTime" /> object that is set to the current date and time on this computer, expressed as the local time.</summary>
<returns>An object whose value is the current local date and time.</returns>
val emp: SqlDataProvider<...>.dataContext.main.EmployeesEntity
val row: SqlDataProvider<...>.dataContext.main.OrdersEntity
SqlDataProvider<...>.dataContext.mainSchema.main.Orders.Create() : SqlDataProvider<...>.dataContext.main.OrdersEntity
SqlDataProvider<...>.dataContext.mainSchema.main.Orders.Create(data: (string * obj) seq) : SqlDataProvider<...>.dataContext.main.OrdersEntity
<summary>Item array of database columns: </summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.CustomerId: string with get, set
<summary>CustomerID: nchar(5)</summary>
property SqlDataProvider<...>.dataContext.main.CustomersEntity.CustomerId: string with get, set
<summary>CustomerID: nchar(5)</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.EmployeeId: int64 with get, set
<summary>EmployeeID: integer</summary>
property SqlDataProvider<...>.dataContext.main.EmployeesEntity.EmployeeId: int64 with get, set
<summary>EmployeeID: integer</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.Freight: decimal with get, set
<summary>Freight: money</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.OrderDate: DateTime with get, set
<summary>OrderDate: datetime</summary>
DateTime.AddDays(value: float) : DateTime
property SqlDataProvider<...>.dataContext.main.OrdersEntity.RequiredDate: DateTime with get, set
<summary>RequiredDate: datetime</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.ShipAddress: string with get, set
<summary>ShipAddress: nvarchar(60)</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.ShipCity: string with get, set
<summary>ShipCity: nvarchar(15)</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.ShipName: string with get, set
<summary>ShipName: nvarchar(40)</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.ShipPostalCode: string with get, set
<summary>ShipPostalCode: nvarchar(10)</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.ShipRegion: string with get, set
<summary>ShipRegion: nvarchar(15)</summary>
property SqlDataProvider<...>.dataContext.main.OrdersEntity.ShippedDate: DateTime with get, set
<summary>ShippedDate: datetime</summary>
SqlDataProvider<...>.dataContext.SubmitUpdates() : Unit
<summary>Save changes to data-source. May throws errors: To deal with non-saved items use GetUpdates() and ClearUpdates().</summary>
val update: obj
member Common.SqlEntity.Delete: unit -> unit
type Employee = { FirstName: string LastName: string }
Multiple items
val string: value: 'T -> string

--------------------
type string = String
val mvps1: Employee list
Multiple items
module List from FSharp.Data.Sql

--------------------
module List from Microsoft.FSharp.Collections

--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
val map: mapping: ('T -> 'U) -> list: 'T list -> 'U list
val x: Employee
val row: SqlDataProvider<...>.dataContext.main.EmployeesEntity
SqlDataProvider<...>.dataContext.mainSchema.main.Employees.Create() : SqlDataProvider<...>.dataContext.main.EmployeesEntity
SqlDataProvider<...>.dataContext.mainSchema.main.Employees.Create(data: (string * obj) seq) : SqlDataProvider<...>.dataContext.main.EmployeesEntity
<summary>Item array of database columns: FirstName,LastName</summary>
SqlDataProvider<...>.dataContext.mainSchema.main.Employees.Create(FirstName: string, LastName: string) : SqlDataProvider<...>.dataContext.main.EmployeesEntity
property SqlDataProvider<...>.dataContext.main.EmployeesEntity.FirstName: string with get, set
<summary>FirstName: nvarchar(10)</summary>
Employee.FirstName: string
property SqlDataProvider<...>.dataContext.main.EmployeesEntity.LastName: string with get, set
<summary>LastName: nvarchar(20)</summary>
Employee.LastName: string
val mvps2: Employee list
type Employee2 = { Id: int64 FirstName: string LastName: string }
Multiple items
val int64: value: 'T -> int64 (requires member op_Explicit)

--------------------
type int64 = Int64

--------------------
type int64<'Measure> = int64
val updateEmployee: employee: Employee2 -> Unit
val employee: Employee2
val foundEmployeeMaybe: SqlDataProvider<...>.dataContext.main.EmployeesEntity option
val query: Linq.QueryBuilder
val p: SqlDataProvider<...>.dataContext.main.EmployeesEntity
custom operation: where (bool) Calls Linq.QueryBuilder.Where
Employee2.Id: int64
custom operation: select ('Result) Calls Linq.QueryBuilder.Select
union case Option.Some: Value: 'T -> Option<'T>
custom operation: exactlyOneOrDefault Calls Linq.QueryBuilder.ExactlyOneOrDefault
val foundEmployee: SqlDataProvider<...>.dataContext.main.EmployeesEntity
Employee2.FirstName: string
Employee2.LastName: string
union case Option.None: Option<'T>
val updateEmployee': employee: Employee2 -> Unit
val iter: action: ('T -> unit) -> source: 'T seq -> unit
val e: SqlDataProvider<...>.dataContext.main.EmployeesEntity
val john: Employee2
val map: mapping: ('T -> 'U) -> source: 'T seq -> 'U seq
val x: SqlDataProvider<...>.dataContext.main.EmployeesEntity
property Common.SqlEntity.ColumnValues: (string * obj) seq with get
val toList: source: 'T seq -> 'T list
val twins: List<Common.SqlEntity>
 Retrieve the FSharp.Data.Sql.Common.SqlEntity objects
SqlDataProvider<...>.dataContext.GetUpdates() : List<Common.SqlEntity>
SqlDataProvider<...>.dataContext.ClearUpdates() : List<Common.SqlEntity>
namespace System.Transactions
val scope: TransactionScope
Multiple items
type TransactionScope = interface IDisposable new: unit -> unit + 13 overloads member Complete: unit -> unit member Dispose: unit -> unit
<summary>Makes a code block transactional. This class cannot be inherited.</summary>

--------------------
TransactionScope() : TransactionScope
   (+0 other overloads)
TransactionScope(transactionToUse: Transaction) : TransactionScope
   (+0 other overloads)
TransactionScope(asyncFlowOption: TransactionScopeAsyncFlowOption) : TransactionScope
   (+0 other overloads)
TransactionScope(scopeOption: TransactionScopeOption) : TransactionScope
   (+0 other overloads)
TransactionScope(transactionToUse: Transaction, scopeTimeout: System.TimeSpan) : TransactionScope
   (+0 other overloads)
TransactionScope(transactionToUse: Transaction, asyncFlowOption: TransactionScopeAsyncFlowOption) : TransactionScope
   (+0 other overloads)
TransactionScope(scopeOption: TransactionScopeOption, scopeTimeout: System.TimeSpan) : TransactionScope
   (+0 other overloads)
TransactionScope(scopeOption: TransactionScopeOption, transactionOptions: TransactionOptions) : TransactionScope
   (+0 other overloads)
TransactionScope(scopeOption: TransactionScopeOption, asyncFlowOption: TransactionScopeAsyncFlowOption) : TransactionScope
   (+0 other overloads)
TransactionScope(transactionToUse: Transaction, scopeTimeout: System.TimeSpan, interopOption: EnterpriseServicesInteropOption) : TransactionScope
   (+0 other overloads)
type TransactionScopeOption = | Required = 0 | RequiresNew = 1 | Suppress = 2
<summary>Provides additional options for creating a transaction scope.</summary>
field TransactionScopeOption.Required: TransactionScopeOption = 0
type TransactionOptions = member Equals: obj: obj -> bool + 1 overload member GetHashCode: unit -> int static member (<>) : x: TransactionOptions * y: TransactionOptions -> bool static member (=) : x: TransactionOptions * y: TransactionOptions -> bool member IsolationLevel: IsolationLevel member Timeout: TimeSpan
<summary>Contains additional information that specifies transaction behaviors.</summary>
type IsolationLevel = | Serializable = 0 | RepeatableRead = 1 | ReadCommitted = 2 | ReadUncommitted = 3 | Snapshot = 4 | Chaos = 5 | Unspecified = 6
<summary>Specifies the isolation level of a transaction.</summary>
field IsolationLevel.ReadCommitted: IsolationLevel = 2
type TransactionScopeAsyncFlowOption = | Suppress = 0 | Enabled = 1
<summary>Specifies whether transaction flow across thread continuations is enabled for <see cref="T:System.Transactions.TransactionScope" />.</summary>
field TransactionScopeAsyncFlowOption.Enabled: TransactionScopeAsyncFlowOption = 1
val ctx: obj
TransactionScope.Complete() : unit
SqlDataProvider<...>.dataContext.SubmitUpdatesAsync() : Threading.Tasks.Task
<summary>Save changes to data-source. May throws errors: Use Async.Catch and to deal with non-saved items use GetUpdates() and ClearUpdates().</summary>
val jane: SqlDataProvider<...>.dataContext.main.EmployeesEntity
property Common.SqlEntity.OnConflict: Common.OnConflict with get, set
<summary> Determines what should happen when saving this entity if it is newly-created but another entity with the same primary key already exists </summary>
type OnConflict = | Throw | Update | DoNothing
<summary> Specifies how to handle conflicts when inserting records with duplicate primary keys. Currently supported only on databases that have UPSERT capabilities. </summary>
union case Common.OnConflict.Update: Common.OnConflict
<summary> If the primary key already exists, updates the existing row's columns to match the new entity. Currently supported only on PostgreSQL 9.5+ </summary>
val conditions: bool = true
val c: SqlDataProvider<...>.dataContext.main.EmployeesEntity
Multiple items
type Async = static member AsBeginEnd: computation: ('Arg -> Async<'T>) -> ('Arg * AsyncCallback * objnull -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit) static member AwaitEvent: event: IEvent<'Del,'T> * ?cancelAction: (unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate and 'Del: not null) static member AwaitIAsyncResult: iar: IAsyncResult * ?millisecondsTimeout: int -> Async<bool> static member AwaitTask: task: Task<'T> -> Async<'T> + 1 overload static member AwaitWaitHandle: waitHandle: WaitHandle * ?millisecondsTimeout: int -> Async<bool> static member CancelDefaultToken: unit -> unit static member Catch: computation: Async<'T> -> Async<Choice<'T,exn>> static member Choice: computations: Async<'T option> seq -> Async<'T option> static member FromBeginEnd: beginAction: (AsyncCallback * objnull -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads static member FromContinuations: callback: (('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T> ...

--------------------
type Async<'T>
static member Async.AwaitTask: task: Threading.Tasks.Task -> Async<unit>
static member Async.AwaitTask: task: Threading.Tasks.Task<'T> -> Async<'T>
static member Async.RunSynchronously: computation: Async<'T> * ?timeout: int * ?cancellationToken: Threading.CancellationToken -> 'T
val don: SqlDataProvider<...>.dataContext.main.EmployeesEntity
val employeeId: int = 123
val createSomeItem: data: (string * obj) seq -> SqlDataProvider<...>.dataContext.main.EmployeesEntity
val data: (string * obj) seq
Multiple items
val seq: sequence: 'T seq -> 'T seq

--------------------
type 'T seq = Collections.Generic.IEnumerable<'T>
type obj = Object
val x: obj
Object.ToString() : string
union case CanonicalOp.ToUpper: CanonicalOp
<summary> Converts string to uppercase </summary>
union case CanonicalOp.Replace: SqlItemOrColumn * SqlItemOrColumn -> CanonicalOp
<summary> Replaces occurrences of a substring with another substring </summary>
val box: value: 'T -> objnull
val bdate: DateTime
DateTime.Parse(s: string) : DateTime
DateTime.Parse(s: string, provider: IFormatProvider) : DateTime
DateTime.Parse(s: ReadOnlySpan<char>, provider: IFormatProvider) : DateTime
DateTime.Parse(s: string, provider: IFormatProvider, styles: Globalization.DateTimeStyles) : DateTime
DateTime.Parse(s: ReadOnlySpan<char>, ?provider: IFormatProvider, ?styles: Globalization.DateTimeStyles) : DateTime
DateTime.AddYears(value: int) : DateTime
property DateTime.UtcNow: DateTime with get
<summary>Gets a <see cref="T:System.DateTime" /> object that is set to the current date and time on this computer, expressed as the Coordinated Universal Time (UTC).</summary>
<returns>An object whose value is the current UTC date and time.</returns>
val failwith: message: string -> 'T
DateTime.ToString() : string
DateTime.ToString( format: string) : string
DateTime.ToString(provider: IFormatProvider) : string
DateTime.ToString( format: string, provider: IFormatProvider) : string
val others: string * obj
val filter: predicate: ('T -> bool) -> source: 'T seq -> 'T seq
val key: string
val append: source1: 'T seq -> source2: 'T seq -> 'T seq
property SqlDataProvider<...>.dataContext.main.EmployeesEntity.BirthDate: DateTime with get, set
<summary>BirthDate: datetime</summary>
member Common.SqlEntity.SetColumn: key: string * value: 't -> unit
val setIfExists: columnName: string -> unit
val columnName: string
member Common.SqlEntity.HasColumn: key: string * ?comparison: StringComparison -> bool
type StringComparison = | CurrentCulture = 0 | CurrentCultureIgnoreCase = 1 | InvariantCulture = 2 | InvariantCultureIgnoreCase = 3 | Ordinal = 4 | OrdinalIgnoreCase = 5
<summary>Specifies the culture, case, and sort rules to be used by certain overloads of the <see cref="M:System.String.Compare(System.String,System.String)" /> and <see cref="M:System.String.Equals(System.Object)" /> methods.</summary>
field StringComparison.InvariantCultureIgnoreCase: StringComparison = 3

Type something to start searching.