f# - 在 F# 中使用用于 SQL Server 的 SqlDataProvider 更新数据库行
问题描述
我是 F# 的新手,我正在尝试使用SqlDataProvider
.
我想要完成的事情是更新我使用 Individuals 属性预取的 Db 行。然后我正在更改字段并提交更新,但似乎SqlDataProvider
没有跟踪更改。
这是代码:
let context = SqlFunctions.Sql.GetDataContext()
let engeneering = context.HumanResources.Department.Individuals.``1``
engeneering.Name <- "Eng."
context.SubmitUpdates()
SqlFunction.Sql
实现如下:
module SqlFunctions
open FSharp.Data.Sql
type Sql = SqlDataProvider<Common.DatabaseProviderTypes.MSSQLSERVER,
"Server=************;Database=AdventureWorks2014;Trusted_Connection=True;">
解决方案
欢迎来到社区!
虽然 SqlDataProvider 是一个出色的工具,但如果您愿意使用它,我建议您使用一些更简单的构造。我想很多时候,当新人加入时,他们会被所有花哨的玩具所吸引,以至于很容易忽略它仍然只是普通的旧 .NET的事实。
话虽如此,我说我们从小处着手,大到结束。我们将通过直接查看您的问题范围来实现这一点,并且在 F# 的真正本质中,我们自己编写了如此漂亮的小函数,以使最终结果简洁明了。
我们的最终目标是支持这样的语法:
// 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
为此,您实际上只需要很少的代码,这是 F# 的主要优点之一。我们知道我们需要:
- 一种创建连接的方式(即连接工厂)
- 一种执行语句的方法(即
INSERT
,UPDATE
) - 一种查询记录的方法(即
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 ]
因此,在大约 30 行代码中,我们为自己创建了一个小型、易于理解且(在我看来)自我记录的解决方案。
推荐阅读
- java - 创建 JFrame 时 Java 崩溃
- function - 编译器中止测试
- python - 使用 QAbstractListModel 从 python 访问 QML 中的列表元素
- python - 自 macOS Catalina 以来,miniconda 将不再管理 python 环境
- c - 你如何在C中制作一个FIFO数组
- android - Android工作室展示
- python - 债券组合凸性最大化
- python-3.x - 将字符串列的最后一个值扩展到 groupby Pandas Dataframe
- ios - 为什么我在 SwiftUI 中更改他后发布的 Array 没有更改?
- r - 如何在ggline中绘制多条线