12

I am using the type expression:

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

This works great at compile time (I have full access to all the db types), but it fails at run time. I presume it's because the config file generated in the console application's bin directory is named something else, such as MyAppName.exe.config, and therefore the App.config file is not found.

Certainly, for an ASP.NET MVC type app that uses web.config, there's no issue because the compile and runtime config filenames are the same.

Fortunately, placing a duplicate App.config in the bin directory does remediate the problem, but is that what we are expected to do? Any thoughts?

Troy Alford
  • 26,660
  • 10
  • 64
  • 82
  • 3
    This is the way how `App.config` works. It is first being looked for a top-level calling assembly. See [this Q](http://stackoverflow.com/questions/3569336/visual-c-sharp-app-config-file-for-a-referenced-assembly) for details. Also notice that `App.config` is actually renamed to `MyAppName.exe.config` during build time, and you may need proper calling your newly created one. – Be Brave Be Like Ukraine Dec 07 '12 at 18:37
  • @bytebuster That's certainly true. However the SqlDataConnection type provider doesn't seem to be aware of this fact and still insists on the file "app.config" to be there, even if `ConfigFile` is not specified explicitly (in which case app.config should be used as the default.) – afrischke Dec 08 '12 at 06:04
  • I've been thinking about this myself. Maybe you'll find this question and answer helpful: http://stackoverflow.com/a/19459561/952606 – spacedoom Oct 19 '13 at 20:47

2 Answers2

1

The description of how the type provider definition works is misleading - the value in the typedef really only matters at code/compile time, and as a default at runtime. However, as you've noted, it isn't very smart about finding the correct config file at runtime.

You can accomplish what you want by passing the connection string as a parameter to GetDataContext:

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

...or if you also want to make it work in F# interactive, wrap it like so:

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

(Note that you will need a reference to System.Configuration.)

Overlord Zurg
  • 3,430
  • 2
  • 22
  • 27
0

I don't have a VS2012 on this PC but this should be what you're looking for :

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>
andri
  • 1,010
  • 1
  • 9
  • 12