F# SqlCommandProvider 将 eval 延迟到运行时
F# SqlCommandProvider defer eval until runtime
我正在尝试使用 SqlCommandProvider(FSharp.Data.SqlClient 的一部分)创建一个不存在的列,然后设置一个约束(自引用)。问题是它不会编译,因为它检测到作为约束一部分的列尚不存在。我尝试将它包装在另一个 IF 块中,但无济于事。
[<Literal>]
let CreateParentColumn = "
IF COL_LENGTH('Company', 'ParentId') IS NULL
BEGIN
ALTER TABLE Company
ADD ParentId INT
ALTER TABLE Company
ADD CONSTRAINT FK_ParentIdCompanyId FOREIGN KEY (ParentId)
REFERENCES Company(CompanyId);
END
"
type CreateParentIdColumn = SqlCommandProvider<CreateParentColumn, connectionString>
我非常不希望使用动态 sql。我想知道是否有一种方法可以推迟评估,以便它 运行 正确(注意,查询本身 运行 在 SQL Management Studio 中很好)
Error 1 The type provider 'FSharp.Data.SqlCommandProvider' reported an error: Foreign key 'FK_ParentIdCustomerId' references invalid column 'ParentId' in referencing table 'Company'.
Could not create constraint. See previous errors.
简短的回答是"No, this cannot be done"。
更详尽的答案是"This cannot be done for the fundamental reason: run time database schema features should be already present at compile time in order to be anyhow utilized by FSharp.Data.SqlClient
type provider"。
仅从学术兴趣的角度来看,在 运行 时间在数据库中创建额外的列和约束不是问题(尽管这是一种非常不寻常的做法)并且不需要涉及动态 SQL 用于此目的。可以通过将普通 ADO 与类型提供程序并排使用来轻松实现:
use cmd = new System.Data.SqlClient.SqlCommand(CreateParentColumn, connectionString)
cmd.ExecuteNonQuery() |> ignore
但实际问题是这个新创建的列在 FSharp.Data.SqlClient
类型提供程序上下文中没有任何用处,因为它不
在编译时还存在于数据库模式中,无论如何都可以被类型提供者使用。
换句话说,FSharp.Data.SqlClient
类型提供程序在 运行 时不执行任何操作,它的工作已经在编译时完成。
我正在尝试使用 SqlCommandProvider(FSharp.Data.SqlClient 的一部分)创建一个不存在的列,然后设置一个约束(自引用)。问题是它不会编译,因为它检测到作为约束一部分的列尚不存在。我尝试将它包装在另一个 IF 块中,但无济于事。
[<Literal>]
let CreateParentColumn = "
IF COL_LENGTH('Company', 'ParentId') IS NULL
BEGIN
ALTER TABLE Company
ADD ParentId INT
ALTER TABLE Company
ADD CONSTRAINT FK_ParentIdCompanyId FOREIGN KEY (ParentId)
REFERENCES Company(CompanyId);
END
"
type CreateParentIdColumn = SqlCommandProvider<CreateParentColumn, connectionString>
我非常不希望使用动态 sql。我想知道是否有一种方法可以推迟评估,以便它 运行 正确(注意,查询本身 运行 在 SQL Management Studio 中很好)
Error 1 The type provider 'FSharp.Data.SqlCommandProvider' reported an error: Foreign key 'FK_ParentIdCustomerId' references invalid column 'ParentId' in referencing table 'Company'. Could not create constraint. See previous errors.
简短的回答是"No, this cannot be done"。
更详尽的答案是"This cannot be done for the fundamental reason: run time database schema features should be already present at compile time in order to be anyhow utilized by FSharp.Data.SqlClient
type provider"。
仅从学术兴趣的角度来看,在 运行 时间在数据库中创建额外的列和约束不是问题(尽管这是一种非常不寻常的做法)并且不需要涉及动态 SQL 用于此目的。可以通过将普通 ADO 与类型提供程序并排使用来轻松实现:
use cmd = new System.Data.SqlClient.SqlCommand(CreateParentColumn, connectionString)
cmd.ExecuteNonQuery() |> ignore
但实际问题是这个新创建的列在 FSharp.Data.SqlClient
类型提供程序上下文中没有任何用处,因为它不
在编译时还存在于数据库模式中,无论如何都可以被类型提供者使用。
换句话说,FSharp.Data.SqlClient
类型提供程序在 运行 时不执行任何操作,它的工作已经在编译时完成。