首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F# - FSharp.Data.SqlClient -获取标识值后更新行

F# - FSharp.Data.SqlClient -获取标识值后更新行
EN

Stack Overflow用户
提问于 2019-01-02 21:48:16
回答 1查看 236关注 0票数 0

假设我有以下几点:

SQL

创建名为Clm的数据库,然后运行以下脚本:

代码语言:javascript
复制
CREATE TABLE dbo.ModelData(
    modelId bigint IDENTITY(1,1) NOT NULL,
    numberOfAminoAcids int NOT NULL,
    maxPeptideLength int NOT NULL,
    seed int NOT NULL,
    fileStructureVersion nvarchar(50) NOT NULL,
    modelData nvarchar(max) NOT NULL,
    createdOn datetime NOT NULL,
 CONSTRAINT PK_ModelData PRIMARY KEY CLUSTERED 
(
    modelId ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON PRIMARY
) ON PRIMARY TEXTIMAGE_ON PRIMARY
GO
ALTER TABLE dbo.ModelData ADD  CONSTRAINT DF_ModelData_createdOn  DEFAULT (getdate()) FOR createdOn
GO

F#

代码语言:javascript
复制
[<Literal>]
let ClmDbName = "Clm"

[<Literal>]
let AppConfigFile = __SOURCE_DIRECTORY__ + "\.\App.config"

[<Literal>]
let ClmConnectionString = "Server=localhost;Database=" + ClmDbName + ";Integrated Security=SSPI"

[<Literal>]
let ClmSqlProviderName = "name=" + ClmDbName

type ClmDB = SqlProgrammabilityProvider<ClmSqlProviderName, ConfigFile = AppConfigFile>
type ModelDataTable = ClmDB.dbo.Tables.ModelData
type ModelDataTableRow = ModelDataTable.Row

type ModelDataTableData = 
    SqlCommandProvider<"select * from dbo.ModelData where modelId = @modelId", ClmConnectionString, ResultType.DataReader>

App.config

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <connectionStrings configSource="db.config" />
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>

db.config

代码语言:javascript
复制
<connectionStrings>
    <add name="Clm" connectionString="Data Source=localhost;Initial Catalog=Clm;Integrated Security=SSPI" />
</connectionStrings>

我需要从表ModelData中获取SQL值。它在代码中的某个地方使用。因此,我有以下函数来添加带有一些默认值的新行,然后返回标识值。

代码语言:javascript
复制
let getNewModelDataId (conn : SqlConnection) =
    let t = new ModelDataTable()
    let r = 
        t.NewRow(
                numberOfAminoAcids = 0,
                maxPeptideLength = 0,
                seed = 0,
                fileStructureVersion = "",
                modelData = "",
                createdOn = DateTime.Now
                )

    t.Rows.Add r
    t.Update(conn) |> ignore
    r.modelId

let openConnIfClosed (conn : SqlConnection) =
    match conn.State with
    | ConnectionState.Closed -> do conn.Open()
    | _ -> ignore ()

我使用它从数据库中获取modelId的新标识值。

代码语言:javascript
复制
let modelId = getNewModelDataId conn

在大约0.5到1.5小时的执行时间之后,我需要更新一些数据。

代码语言:javascript
复制
use d = new ModelDataTableData(conn)
let t1 = new ModelDataTable()
d.Execute(modelId = modelId) |> t1.Load
let r1 = t1.Rows |> Seq.find (fun e -> e.modelId = modelId)
r1.modelData <- "Some new data..."
t1.Update(conn) |> ignore

其中字符串"Some new data..."表示一些相当大的字符串。这种情况每个modelId只发生一次。上面的代码是有效的。但它看起来太丑了,尤其是t1.Rows |> Seq.find ...☹这个角色,我想我错过了一些关于FSharp.Data.SqlClient类型提供商的东西。如有任何建议,我将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2019-01-04 03:39:00

首先,最明显的错误是:FSharp.Data.SqlClient类型提供者通过其SqlCommandProvider支持任何DML数据修改语句,包括UPDATE。因此,通过将模型拉到客户端、修改并向后推回服务器而不是所有的爵士乐,可以通过以下方式实现

代码语言:javascript
复制
...
use cmd = SqlCommandProvider<
              "UPDATE [dbo].[ModelData] SET [modelData]=@ModelData WHERE [modelId]=@ModelId",
               conn>(conn)
cmd.Execute(ModelData="Some new data...", ModelId=modelId) |> ignore
...

不太明显的问题与identity field的使用有关。听起来,除了唯一地识别每一种新模式之外,它没有任何特殊的角色。因此,与其修补创建假记录,然后从服务器上提取其id,然后用实际值更新具有此id的记录,为什么不只是:

  • 引入一个类型为modelUid的附加列统一标识符
  • 在上面添加一个非聚集索引(如果这很重要的话)
  • 通过使用GUID生成一个新的System.Guid.NewGuid(),开始创建每个新模型
  • 可以任意使用这个GUID值,然后当您准备持久化时,可以使用SQL DML INSERTmodelUid字段使用相同的GUID。

注意,通过这种方法,您还只使用了SqlCommandProvider类型的FSharp.Data.SqlClient类型提供程序,所以事情仍然很简单。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54013601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档