【问题标题】:in F#, when is a "constant string expression" not a "constant string expression"在 F# 中,什么时候是“常量字符串表达式”而不是“常量字符串表达式”
【发布时间】:2016-10-07 16:23:38
【问题描述】:

刚接触 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# 方式”来执行此操作?

【问题讨论】:

  • 您需要在定义上方添加一个 [&lt;Literal&gt;] 属性,除非这不起作用,因为字符串不是常量(类型提供程序选择将其公开为属性,而不是文字字段)。
  • 你是对的。它没有。有没有更好的方法来做到这一点而无需对连接字符串进行硬编码?

标签: entity-framework f# app-config


【解决方案1】:

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

现在,问一个问题:ConnStr 在编译时是否已知?
不,当然不是,因为您想从配置文件中删除它。

您应该使用的方式是:

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

【讨论】:

  • ConnStr 当然可以在编译时知道,如果 AppSettings 类型提供程序被实现为将其作为文字返回(并且类似的类型提供程序甚至可以选择为两者公开单独的成员编译时和运行时值,让您也可以在运行时做正确的事情)。
  • 是的,那很好。
  • @kvb:但这显然不是 OP 的真正含义。他的错误是他混淆了编译时连接字符串和运行时连接字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-29
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
相关资源
最近更新 更多