2

I've scoured the net for hours and can't do it, so I'm hoping someone can help me with this one.

I've tried to use App.Config directly but constantly had null return. So I've turned to an AppSetting typerprovider. This does return the string expected but I have a problem that no-one so far (via google) has an answer for.

open System.Linq
open FSharp.Data.Sql
open MySql.Data
open FSharp.Configuration 
type Settings = AppSettings<"App.config">

let c = Settings.ConnectionStrings.RaspberryPi 

[<Literal>]
let connection = c //quick attempt to turn c into a literal.

type sql = SqlDataProvider< ConnectionString = c,  ResolutionPath = @"C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.7\Assemblies\v4.5\"  >

I get the message that "This is not a valid constant expression or custom attribute value."

Whilst I'm able to print out the setting the Appsettings provider obtains, it seems I can't use it to connect to a database.

This is the App.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <connectionStrings>
    <add name="raspberryPi" providerName="FSharp.Data.SqlProvider" connectionString="Server=SomeDB.rds.amazonaws.com:3306;Database=SomeDB;Uid=SomeUser;Pwd=APassword" />
  </connectionStrings>
</configuration>

I've turned to the typeprovider as my earlier approach to using System.Configuration to read the file refused to work right, even when I blitzed the output folders and made sure that all the config files were updated.

Please note I'm using a MySQL type provider as well!

Whilst I could use the string directly in the code, my understanding is this is a terrible idea for production code.

Any help would be very gratefully received - I don't mind admitting that this has burned hours today, to my great surprise.

Note - may help others: I've also looked at this answer, this article and this one from the MS Forums

Community
  • 1
  • 1
Richard Griffiths
  • 758
  • 1
  • 11
  • 23
  • 2
    Check out this http://stackoverflow.com/questions/13107676/f-type-provider-for-sql-in-a-class – hocho Sep 08 '15 at 19:43
  • Thanks @hocho - I can't see how to get around the point kvp made unfortunately. I've forked the Fsharp.Configuration project as I really need to find a commercially secure way to bundle the connection string - this seems to be the most promising: if I can find a way to do it. If it wasn't MySQL it would likely be easier perhaps. – Richard Griffiths Sep 10 '15 at 08:15
  • also take a look at this link http://pinksquirrellabs.com/post/2014/05/18/CRUD-Operations-and-Experimental-ODBC-support-in-the-SQLProvider.aspx. You should be able to do something like this: let ctx2 = sql.GetDataContext("some other connection string"), to replace the compile time connection string with one for runtime. (You have a static connection string to database with maybe just the schema for compile time and for runtime have the actual database connection string.) – hocho Sep 10 '15 at 15:49

1 Answers1

1

That won't work, unfortunately. The connection string is being exposed by a read/write static property (Settings.ConnectionStrings.RaspberryPi), which can't be treated as a constant/literal (by design).

It would be possible for someone to write a type provider that does what you want by exposing the connection strings as literal static fields instead of read/write properties, but that's not compatible with updating the application settings, which seems to be a goal of the existing provider. Perhaps you could consider submitting a feature request to the AppSettings project to enable a separate mode that would behave how you want.

kvb
  • 54,864
  • 2
  • 91
  • 133
  • thank you for the explanation. I've got used to basic functional programming but I'm amazed at just impossible this tiny task is in F#. I was after a good secure way to do the connection string for MySQL for a web service. Back to the drawing board I guess :(. Thank you for your help, I can stop banging on that brick wall I think. I don't yet have the skills do a type provider to do it myself. – Richard Griffiths Sep 08 '15 at 22:38