Я использовал FSharpDAL для чтения таблиц данных в базе данных Mysql.Это хорошо работает, но вы должны указать тип записи.Что означает, что для каждой таблицы вы должны определить тип записи.Я хотел бы получить тип записи, сгенерированный автоматически из схемы таблицы.Также, когда столбец таблицы обнуляется, я бы хотел, чтобы поле записи coresponding было типом параметра.
Есть ли что-нибудь, что может это сделать?(пока не появятся провайдеры типов)
Большое спасибо
Примечание. Я пытался сделать свою версию (которая компилирует модуль с типами записей), кажется, работает, но уродливо:@DannyAsher для кода компиляции)
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