Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于MySql数据库表自动生成记录类型,用于FSharpDAL_Mysql_F#_Fsharpcodeprovider - Fatal编程技术网

基于MySql数据库表自动生成记录类型,用于FSharpDAL

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

我一直在使用Mysql数据库读取数据表。它工作得很好,但您必须为其提供记录类型。这意味着您必须为每个表定义一个记录类型。我想从表模式中自动生成记录类型。此外,当表列为空时,我希望coresponding记录字段是一个选项类型

有什么东西可以做到这一点吗?(直到类型提供程序到达)

非常感谢

注意:我已经尝试过使用我的版本(它编译了一个带有记录类型的模块),它似乎可以工作,但很难看:(感谢@DannyAsher提供的编译代码)


我能想到的最好的办法是使用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