1

私はFSharpDALを使用してMysqlデータベースのデータテーブルを読み取っています。うまく機能しますが、レコードタイプを指定する必要があります。つまり、すべてのテーブルに対して、レコードタイプを定義する必要があります。テーブルスキーマから自動的に生成されたレコードタイプを取得したいと思います。また、テーブルの列がnull許容の場合、対応するレコードフィールドをオプションタイプにします。

これを行うことができる何かがそこにありますか?(タイププロバイダーが到着するまで)

どうもありがとう

私が自分のバージョン(レコードタイプでモジュールをコンパイルする)を実行しようとしたことに注意してください。動作しているように見えますが、醜いです:(コンパイルコードを@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
4

1 に答える 1

2

私が考えることができる最も良いことは、VS2010に付属している「xsd.exe」ツールを使用することです。テーブルのXML記述からアセンブリまたはC#ソースファイルを作成できます。

XML記述自体は、クラスのWriteXmlSchemaメソッドからエクスポートできます。DataSet

これはADO.Netバインディングでのみ機能しますが、MySQLはそれらをサポートします。

于 2011-01-08T12:55:37.583 に答える