Я думаю, что ответ Бента дает вам очень хороший DSL для создания стандартных объектов SqlCommand
. Это вполне может быть именно то, что вам нужно — если вам просто нужен более приятный синтаксис для создания пары команд, он будет работать отлично.
Если вы хотите сделать больше с вашими SQL-командами, то у DSL есть одно ограничение, которое заключается в том, что он все еще основан на базовом изменяемом типе SqlCommand
— он выглядит функциональным, но он мутирует объекты под прикрытием, что может привести вас в замешательство. беда.
Более комплексным вариантом было бы определение собственных функциональных типов для захвата домена, то есть типов запросов, которые вы хотите выполнять:
type Parameter =
| Int of int
| VarChar of string
| Text of string
| DateTime of System.DateTime
type Command =
{ Query : string
Timeout : int
Parameters : (string * Parameter) list }
Затем вы можете создавать запросы, используя обычные типы F # (и вы даже можете реализовать DSL, подобный тому, который Бент предложил поверх этого, сохраняя при этом неизменяемость):
let cmd =
{ Query = query
Timeout = 100000
Parameters =
[ "@1", Int 42
"@2", VarChar "answer"
"@3", VarChar (mydate.ToString("yyyy.MM.dd"))
"@4", VarChar "D. Adams"
"@5", DateTime DateTime.Now
"@6", Text filename ] }
Последним битом было бы написать функцию, которая принимает команду и соединение и превращает их в SqlCommand
:
let createSqlCommand cmd connection =
let sql = new SqlCommand(cmd.Query, connection)
sql.CommandTimeout <- cmd.Timeout
for name, par in cmd.Parameters do
let sqlTyp, value =
match par with
| Int n -> SqlDbType.Int, box n
| VarChar s -> SqlDbType.VarChar, box s
| Text s -> SqlDbType.Text, box s
| DateTime dt -> SqlDbType.DateTime, box dt
sql.Parameters.Add(name, sqlTyp).Value <- value
sql
Наилучший подход будет зависеть от вашего варианта использования, а взаимодействие с базами данных по своей сути нечисто, поэтому, возможно, держать вещи изолированными и нечистыми вполне нормально. Хотя я хотел показать это как возможный вариант, если вы хотите быть более функциональным и сосредоточиться на предметной области (используя мощную сторону моделирования на основе предметной области F#!).
person
Tomas Petricek
schedule
15.03.2017