Welcome to the community!
While SqlDataProvider is an excellent tool, if you're open to it, I'd recommend using some simpler constructs. I think often times, when new people join, they're so drawn to all the fancy toys that it can be easy to lose sight of the fact that it's still just plain old .NET.
With that said, I say we start small and finish big. We'll accomplish this by looking directly at your problem scope, and in the true nature of F# write ourselves so nice little functions to make the end result clean & simple.
Our end goals is supporting syntax like this:
// Define a reusable "update department" function
let updateDepartment departmentId name connStr =
use conn = newConnection connStr
exec
"UPDATE HumanResources.Department SET Name = @name WHERE DepartmentId = @departmentId"
[("departmentId", departmentId);("name", name)]
conn
let connStr = "..."
updateDepartment 1 "eng" connStr |> ignore
To accomplish this, you actually need very little code, which is one of the major benefits of F#. We know we need:
- A way to create connections (i.e. connection factory)
- A way to execute statements (i.e.
INSERT, UPDATE)
- A way to query records (i.e.
SELECT)
module SQL =
open System.Data
open System.Data.SqlClient
let newConnection connectionString =
let conn = new SqlConnection(connectionString)
conn.Open()
conn
let createParameter (cmd: SqlCommand) (name, value) =
let p = cmd.CreateParameter()
p.ParameterName <- name
p.Value <- value
p
let addParameter (cmd: SqlCommand) (p : SqlParameter) =
cmd.Parameters.Add(p) |> ignore
let newCommand sql parameters conn =
let cmd = new SqlCommand(connection = conn, cmdText = sql)
cmd.CommandType <- CommandType.Text
let createParam = createParameter cmd
let addParam = addParameter cmd
parameters
|> Seq.iter (fun p -> p |> createParam |> addParam)
cmd
let exec sql param conn =
let cmd = newCommand sql param conn
cmd.ExecuteNonQuery()
let query sql param map conn =
let cmd = newCommand sql param conn
use rd = cmd.ExecuteReader()
[ while rd.Read() do
yield map rd ]
So in about 30 lines of code we've created ourselves a small, well-understood and (in my opinion) self documenting solution.