在F#中,何时一个“常量字符串表达式”不是一个“常量字符串表达式”?

6

我刚接触F#,所以还在逐渐适应“类型推断”。

我正在尝试在F#中使用EntityFramework,但是当我尝试建立连接时,我会收到错误提示说我的连接字符串(从app.config读取)不是“有效的常量表达式或自定义属性值”。如果我硬编码连接字符串,就像你预期的那样,它就可以正常工作。

open FSharp.Configuration
type Settings = AppSettings<"app.config">
let ConnStr = Settings.ConnectionStrings.Model
type private Connection = SqlEntityConnection<ConnectionString=ConnStr, Pluralize = true>

我做错了什么?有没有不同的“F#方式”来解决这个问题?

1
你需要在定义上方添加[<Literal>]属性,但这样做行不通,因为该字符串不是常量(类型提供程序选择将其公开为属性而不是文字字段)。 - kvb
你说得对。它没有。有没有更好的方法来做这个而不是硬编码连接字符串? - mrjawright
1个回答

5

SqlEntityConnection 是一个类型提供程序。类型提供程序在编译时工作(将它们视为编译器插件;或者如果你喜欢Lisp,将它们视为穷人的宏)。因此,所有类型提供程序参数都需要在编译时知道。

现在,问一个问题:在编译时是否知道 ConnStr
当然不知道,因为您希望从配置文件中获取它。

您应该使用以下方式处理:

  1. 硬编码连接字符串,将其指向在编译时可用的数据库。这将给类型提供程序一个机会,在编译时查看数据库,并从中生成所有类型。
  2. 当您调用 Connection.GetDataContext 时,将运行时连接字符串作为参数传递给它。这将告诉它连接到实际在您的配置中指定的任何数据库,而不是您在编译时硬编码的那个。

1
如果实现了AppSettings类型提供程序以将其作为文字返回(甚至类似的类型提供程序可以选择公开编译时和运行时值的单独成员,使您在运行时也能做正确的事情),那么ConnStr肯定可以在编译时知道。 - kvb
是的,那将会很好。 - mrjawright
@kvb:但这显然不是 OP 实际想表达的。他的错误在于混淆了编译时连接字符串和运行时连接字符串。 - Fyodor Soikin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接