2012-12-07 7 views
12

Ich verwende den Ausdruck des Typs:Wie soll man den F # SqlDataConnection TypeProvider mit einer App.Config-Datei verwenden?

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

Dies funktioniert gut bei der Kompilierung (Ich habe vollen Zugang zu allen db-Typen), aber es funktioniert nicht während der Laufzeit. Ich nehme an, dass es ist, weil die Konfigurationsdatei, die im bin Verzeichnis der Konsolenanwendung erzeugt wird, etwas anderes genannt wird, wie MyAppName.exe.config, und deshalb die App.config Datei nicht gefunden wird.

Sicherlich, für eine ASP.NET MVC Typ App, die web.config verwendet, gibt es kein Problem, da die Kompilierung und Laufzeitkonfiguration Dateiname identisch sind.

Zum Glück behebt die Platzierung eines Duplikats App.config im Verzeichnis bin das Problem, aber ist es das, was von uns erwartet wird? Irgendwelche Gedanken?

+3

Dies ist die Art und Weise, wie 'App.config' funktioniert. Zuerst wird nach einer aufrufenden Assembly der obersten Ebene gesucht. Weitere Informationen finden Sie in [this Q] (http://stackoverflow.com/questions/3569336/visual-c-sharp-app-config-file-for-a-reference-assembly). Beachten Sie außerdem, dass "App.config" während der Erstellung tatsächlich in "MyAppName.exe.config" umbenannt wird und dass Sie möglicherweise den neu erstellten Ordner ordnungsgemäß aufrufen müssen. – bytebuster

+0

@bytebuster Das ist sicherlich richtig. Der Provider des Typs SqlDataConnection scheint sich dieser Tatsache jedoch nicht bewusst zu sein und besteht dennoch darauf, dass die Datei "app.config" vorhanden ist, auch wenn "ConfigFile" nicht explizit angegeben ist (in diesem Fall sollte app.config verwendet werden) der Standard.) – afrischke

+0

Ich habe selbst darüber nachgedacht. Vielleicht finden Sie diese Frage und Antwort hilfreich: http://Stackoverflow.com/a/19459561/952606 – spacedoom

Antwort

0

Ich habe keine VS2012 auf diesem PC, aber dies sollte das sein, was Sie suchen:

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> 
+0

Kein Glück! Compiler sagt für 'configfile':" Dies ist kein konstanter Ausdruck oder kein gültiger benutzerdefinierter Attributwert. –

1

Die Beschreibung, wie die Typ-Provider-Definition arbeitet irreführend ist - der Wert in der typedef wirklich kommt nur bei Code/Kompilierzeit und als Standard zur Laufzeit in Frage. Wie Sie jedoch festgestellt haben, ist es nicht sehr schlau, zur Laufzeit die richtige Konfigurationsdatei zu finden.

können Sie erreichen, was Sie wollen, indem Sie die Verbindungszeichenfolge als Parameter an GetDataContext vorbei:

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

... oder wenn Sie es auch wie so in F # interaktiv, wickeln Sie es machen wollen arbeiten:

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

(Beachten Sie, dass Sie einen Verweis auf System.Configuration benötigen.)

+0

Dies ist ungefähr die gleiche Antwort, die oben von lacomoom verlinkt wurde. –