基于MySql数据库表自动生成记录类型,用于FSharpDAL
我一直在使用Mysql数据库读取数据表。它工作得很好,但您必须为其提供记录类型。这意味着您必须为每个表定义一个记录类型。我想从表模式中自动生成记录类型。此外,当表列为空时,我希望coresponding记录字段是一个选项类型 有什么东西可以做到这一点吗?(直到类型提供程序到达) 非常感谢 注意:我已经尝试过使用我的版本(它编译了一个带有记录类型的模块),它似乎可以工作,但很难看:(感谢@DannyAsher提供的编译代码)基于MySql数据库表自动生成记录类型,用于FSharpDAL,mysql,f#,fsharpcodeprovider,Mysql,F#,Fsharpcodeprovider,我一直在使用Mysql数据库读取数据表。它工作得很好,但您必须为其提供记录类型。这意味着您必须为每个表定义一个记录类型。我想从表模式中自动生成记录类型。此外,当表列为空时,我希望coresponding记录字段是一个选项类型 有什么东西可以做到这一点吗?(直到类型提供程序到达) 非常感谢 注意:我已经尝试过使用我的版本(它编译了一个带有记录类型的模块),它似乎可以工作,但很难看:(感谢@DannyAsher提供的编译代码) 我能想到的最好的办法是使用VS2010附带的。它可以根据表的XML描述创
我能想到的最好的办法是使用VS2010附带的。它可以根据表的XML描述创建程序集或C#源文件 XML描述本身可以从
数据集
类的
这只适用于ADO.Net绑定,而不适用于MySQL
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