如何使用F# SqlDataConnection TypeProvider和App.Config文件?

12

我正在使用类型表达式:

type dbSchema = SqlDataConnection<ConnectionStringName="X1", ConfigFile="App.config">

在编译时这个方法非常有效(我可以完全访问所有的db类型),但在运行时会出现问题。我猜测是因为控制台应用程序生成的配置文件位于bin目录中,并且命名为其他名称,比如MyAppName.exe.config,因此无法找到App.config文件。

当然,对于使用web.configASP.NET MVC类型应用程序,没有这个问题,因为编译和运行时的配置文件名是相同的。

幸运的是,在bin目录中放置一个重复的App.config可以解决这个问题,但这是我们期望做的吗?有什么想法吗?


3
这是App.config的工作方式。首先会在顶层调用程序集中查找。有关详细信息,请参见此问答。同时请注意,App.config在构建时实际上被重命名为MyAppName.exe.config,您可能需要适当地调用您新创建的配置文件。 - Be Brave Be Like Ukraine
@bytebuster 这确实是真的。然而,SqlDataConnection 类型提供程序似乎没有意识到这一点,仍然坚持要求文件“app.config”存在,即使没有明确指定 ConfigFile(在这种情况下应该使用 app.config 作为默认值)。 - afrischke
我自己也一直在思考这个问题。也许你会发现这个问题和答案有所帮助: https://dev59.com/ZnfZa4cB1Zd3GeqPRGr9#19459561 - spacedoom
2个回答

1
如何定义类型提供程序的描述有误 - typedef 中的值实际上只在代码/编译时起作用,并且在运行时仅作为默认值。但是,正如您所指出的那样,在运行时找到正确的配置文件并不是很聪明。
您可以通过将连接字符串作为参数传递给 GetDataContext 来实现所需的功能:
type dbSchema = SqlDataConnection<ConnectionStringName="X2">
let db = dbSchema.GetDataContext(ConfigurationManager.ConnectionStrings.["X2"].ConnectionString)

如果您还希望在F#互动环境中使其工作,请这样包装它:

type dbSchema = SqlDataConnection<ConnectionStringName="X2">
#if COMPILED
let db = dbSchema.GetDataContext(ConfigurationManager.ConnectionStrings.["X2"].ConnectionString)
#else
let db = dbSchema.GetDataContext()
#endif

(请注意,您需要引用 System.Configuration。)

这个答案与spacedoom上面链接的答案大致相同。 - Overlord Zurg

0

我在这台电脑上没有VS2012,但这应该是你要找的:

let exeConfigFile = Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location) + ".config"
let defaultConfigFile = "App.config"
let configFile = if File.Exists(exeConfigFile) then exeConfigFile else defaultConfigFile

type dbSchema = SqlDataConnection<ConnectionStringName="X1", ConfigFile=configFile>

运气不好!编译器对于 configfile 表示:“这不是一个常量表达式或有效的自定义属性值。” - Clifford Ritchie

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