Ich habe FSharpDAL verwendet, um Datentabellen in Mysql-Datenbank zu lesen. Es funktioniert gut, aber Sie müssen es den Datensatztyp bereitstellen. Das bedeutet, dass Sie für jede Tabelle einen Satztyp definieren müssen. Ich möchte den Datensatztyp automatisch aus dem Tabellenschema generieren lassen. Wenn die Tabellenspalte nullfähig ist, möchte ich auch, dass das entsprechende Datensatzfeld ein Optionstyp ist.Automatische Generierung von Datensatztyp basierend auf MySql-Datenbanktabellen zur Verwendung in FSharpDAL
Gibt es da draußen etwas, das das tun kann? (Bis Typ-Provider ankommen)
Vielen Dank
Hinweis habe ich versucht, meine Version zu tun (was ein Modul mit den Aufzeichnungen Typen kompiliert), scheint zu funktionieren, aber seine ugly: (Danke für die @DannyAsher Kompilieren Code)
let typeString conString (table:string) =
use con = new MySqlConnection(conString)
con.Open()
use cmd = new MySqlCommand(("select * from "+table),con)
let schema = cmd.ExecuteReader().GetSchemaTable()
let schemaData =
[for col in schema.Columns do
yield! [for row in schema.Rows ->
//System.Console.WriteLine(col.ColumnName+" "+string row.[col])
(col.ColumnName),(string row.[col])]]
|>Seq.filter(fun (name,_) ->
((name="ColumnName")||(name="DataType"))||(name="AllowDBNull"))
|>Seq.groupBy(fst)
|>Seq.cache
let columnsNames = snd(schemaData|>Seq.nth(0))
let colDataTypes = snd(schemaData|>Seq.nth(1))
let optionType = snd(schemaData|>Seq.nth(2))
let toCompileType =
(Seq.zip3 columnsNames colDataTypes optionType
|> Seq.map(fun ((_,colName),(_,colType),(_,allowNull)) ->
if allowNull="True" then
colName+":"+colType+" option;"
else
colName+":"+colType+";"
)
|>Seq.fold(fun res elem ->res+elem) ("type "+table+"={"))+"}"
toCompileType
#r "FSharp.Compiler.dll"
#r "FSharp.Compiler.CodeDom.dll"
open System
open System.IO
open System.CodeDom.Compiler
open Microsoft.FSharp.Compiler.CodeDom
let CompileFSharpString(str, assemblies, output) =
use pro = new FSharpCodeProvider()
let opt = CompilerParameters(assemblies, output)
let res = pro.CompileAssemblyFromSource(opt, [|str|])
if res.Errors.Count = 0 then
Some(FileInfo(res.PathToAssembly))
else
None
let (++) v1 v2 = Path.Combine(v1, v2)
let defaultAsms = [||]
let randomFile() = __SOURCE_DIRECTORY__ ++ Path.GetRandomFileName() + ".dll"
type System.CodeDom.Compiler.CodeCompiler with
static member CompileFSharpString (str, ?assemblies, ?output) =
let assemblies = defaultArg assemblies defaultAsms
let output = defaultArg output (randomFile())
CompileFSharpString(str, assemblies, output)
let tables = [|"users";"toys"|]
let compileTypes conString tables =
let m= "namespace Toto
module Types =
"
let str = tables|>Seq.fold(fun res elem ->
res+"\n "+(typeString conString elem)) m
// Create the assembly
CodeCompiler.CompileFSharpString(str)
let conString = "connectionstring"
let file =compileTypes conString tables
#r "theFileName"
open Toto.Types
danke, ich werde es untersuchen. – jlezard