ho scritto il seguente codice per eseguire uno StoredProc SQLServer in F #Connessioni di database e F #
module SqlUtility =
open System
open System.Data
open System.Data.SqlClient
SqlUtility.GetSqlConnection "MyDB"
|> Option.bind (fun con -> SqlUtility.GetSqlCommand "dbo.usp_MyStordProc" con)
|> Option.bind (fun cmd ->
let param1 = new SqlParameter("@User", SqlDbType.NVarChar, 50)
param1.Value <- user
cmd.Parameters.Add(param1) |> ignore
let param2 = new SqlParameter("@PolicyName", SqlDbType.NVarChar, 10)
param2.Value <- policyName
cmd.Parameters.Add(param2) |> ignore
Some(cmd)
)
|> Option.bind (fun cmd -> SqlUtility.ExecuteReader cmd)
|> Option.bind (fun rdr -> ExtractValue rdr)
let GetSqlConnection (conName : string) =
let conStr = ConfigHandler.GetConnectionString conName
try
let con = new SqlConnection(conStr)
con.Open()
Some(con)
with
| :? System.Exception as ex -> printfn "Failed to connect to DB %s with Error %s " conName ex.Message; None
| _ -> printfn "Failed to connect to DB %s" conName; None
let GetSqlCommand (spName : string) (con : SqlConnection) =
let cmd = new SqlCommand()
cmd.Connection <- con
cmd.CommandText <- spName
cmd.CommandType <- CommandType.StoredProcedure
Some(cmd)
let AddParameters (cmd : SqlCommand) (paramList : SqlParameter list) =
paramList |> List.iter (fun p -> cmd.Parameters.Add p |> ignore)
let ExecuteReader (cmd : SqlCommand) =
try
Some(cmd.ExecuteReader())
with
| :? System.Exception as ex -> printfn "Failed to execute reader with error %s" ex.Message; None
ho più problemi con questo codice
In primo luogo l'uso ripetuto di Option.bind è molto irritante ... e aggiunge rumore Ho bisogno di un modo più chiaro per verificare se l'output fosse None e, in caso contrario, procedere.
Alla fine dovrebbe esserci una funzione di pulizia in cui dovrei essere in grado di chiudere + disporre il lettore, il comando e la connessione. Ma attualmente alla fine della pipeline tutto quello che ho è il lettore.
La funzione che aggiunge parametri ... sembra che stia modificando lo "stato" del parametro di comando perché il tipo di ritorno è sempre lo stesso comando che è stato inviato ... con qualche stato aggiunto. Mi chiedo come avrebbe fatto un programmatore funzionale più esperto.
Visual Studio mi invia un avviso in ognuno dei punti in cui gestisco le eccezioni. cosa c'è di sbagliato in questo" dice
Questo test tipo o abbattuti saranno sempre tenere
Il modo in cui voglio questo codice a guardare è questo
Sia X: MyRecord seq = GetConnection 'con' |> GetCommand "cmd" |> addParameter "@name" SqlDbType.NVarchar 50 |> addParameter "@policyname" SqlDbType.NVarchar 50 |> ExecuteReader |> FunctionToReadAndGenerateSeq |> CleanEverything
Potete consigliarmi come posso prendere il mio codice al livello desiderato e anche a qualsiasi altro miglioramento?