在Azure网站上运行的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):错误FS3033:类型提供程序 &#39; FSharp.Data.Sql.SqlTypeProvider&#39;报错:网络相关 建立连接时发生或特定于实例的错误 SQL Server。服务器未找到或无法访问。校验 实例名称正确且SQL Server配置为 允许远程连接。 (提供者:SQL网络接口,错误:52 - 无法找到本地数据库运行时安装。验证是否已正确安装SQL Server Express以及本地数据库 运行时功能已启用。)
天文站点中没有connStr
中的设计时数据库,但我认为这就是为什么我们有GetDataContext
重载,它需要在运行时使用连接字符串?
是因为它是作为脚本运行而不是在创建TypeProvider
时尝试访问数据库的已编译代码?
如果是的话,这是否意味着我唯一的选择是编译并提供数据库代码作为我在Suave FSX脚本中加载和使用的编译程序集?
从配置文件中读取连接字符串不能很好地工作,因为它位于azure站点中。我真的需要从环境变量(在azure管理界面中设置)中获取连接字符串。
答案 0 :(得分:3)
嗯,这有点不幸 - 正如@Fyodor在评论中提到的,问题是Azure的基于脚本的部署实际上是在Azure机器上编译脚本 - 所以你需要有一个静态解析的连接适用于Azure的字符串。
有两种选择:
使用已编译的项目。如果您在本地编译F#代码并将编译后的代码部署到Azure,它将起作用。可悲的是,没有好的样本。
做一些聪明的技巧,使编译时脚本可以访问连接字符串。
将PR发送到SQL提供程序,以便您可以为其指定环境变量的名称,并从中读取连接字符串。
我认为(3)实际上是非常好用且有用的功能。
我不一定确定最好的做法(2)是什么。但我认为您可以修改app.azure.fsx
,以便创建一个包含以下内容的文件(例如connection.fsx
):
module Connection
let [<Literal>] ConnString = "<Contents of SQLAZURECONNSTR_QUERIES>"
然后app.fsx
可以加载此脚本并在SQL类型提供程序的参数中使用Connection.ConnString
。