Azure 上 Suave 中的 SqlDataProvider 连接字符串

SqlDataProvider connection string in Suave on Azure

在 Azure 网站 运行ning 中的 fsx 脚本中执行时,我无法让 SqlDataProvider 工作。

我从 Tomas Petrecek 在这里的样本开始:https://github.com/tpetricek/Dojo-Suave-FsHome

简而言之,它是一个使用 IIS httpPlatformHandler 执行的 FSX 脚本,因此对我的 Azure 网站的所有 http 请求都会转发到我的 F# 脚本。

F# 脚本使用 Suave 处理请求。

当我尝试向我的 HTTP 处理程序添加一些数据库访问时,我遇到了问题。

有问题的代码如下所示:

[<Literal>]
let connStr = "Server=(localdb)\v11.0;Initial Catalog=My_Database;Integrated Security=true;" 
[<Literal>]
let resolutionFolder = __SOURCE_DIRECTORY__
FSharp.Data.Sql.Common.QueryEvents.SqlQueryEvent |> Event.add (printfn "Executing SQL: %s")

// the following line fails when executing in azure
type db = SqlDataProvider<connStr, Common.DatabaseProviderTypes.MSSQLSERVER, ResolutionPath = resolutionFolder>

let saveData someDataToSave =
  let ctx = db.GetDataContext(Environment.GetEnvironmentVariable("SQLAZURECONNSTR_QUERIES"))
  .....
  /// code using the context here

当我在本地 运行 它工作得很好,但是当我将它部署到 azure 站点时,它会在创建 type db 的那一行失败。

错误信息是(第 70 行是 type db = ...:

D:\home\site\wwwroot\app.fsx(70,11): error FS3033: The type provider 'FSharp.Data.Sql.SqlTypeProvider' reported an error: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 52 - Unable to locate a Local Database Runtime installation. Verify that SQL Server Express is properly installed and that the Local Database Runtime feature is enabled.)

connStr 中的设计时数据库在 azure 站点中不可用,但我认为这就是我们有 GetDataContext 重载的原因,该重载需要在 运行-时间?

创建 TypeProvider 时是否因为它 运行 作为脚本而不是编译代码试图访问数据库? 如果是,是否意味着我唯一的选择是编译并提供数据库代码作为我在 Suave FSX 脚本中加载和使用的编译程序集?

从配置文件中读取连接字符串效果不佳,因为这是在 Azure 站点中。我真的需要从一个环境变量中获取连接字符串(这是在 azure 管理界面中设置的)。

嗯,这有点不幸——正如@Fyodor 在评论中提到的,问题是基于脚本的 Azure 部署实际上是在 Azure 机器上编译脚本——所以你需要有一个静态的——已解析可在 Azure 上运行的连接字符串。

有两种选择:

  1. 改用已编译的项目。如果您在本地编译 F# 代码并将编译后的代码部署到 Azure,它就可以正常工作。可悲的是,没有好的样本。

  2. 使用一些巧妙的技巧使脚本在编译时可以访问连接字符串。

  3. 向 SQL 提供者发送一个 PR,这样你就可以给它一个环境变量的名称,它会从那里读取连接字符串。

我认为 (3) 实际上是非常好的和有用的功能。

我不确定 (2) 的最佳方法是什么。但我认为您可以修改 app.azure.fsx 以便它创建一个包含以下内容的文件(比如 connection.fsx):

module Connection
let [<Literal>] ConnString = "<Contents of SQLAZURECONNSTR_QUERIES>"

然后 app.fsx 可以加载此脚本并在 SQL 类型提供程序的参数中使用 Connection.ConnString