2011-01-07 1 views
1

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

これを実行できることはありますか?

おかげで、私は(レコードのタイプとモジュールをコンパイルする)私のバージョンを行うことを試みているたくさん

注意を(タイププロバイダが到着するまで)、動作するようですが、その醜い:(感謝のため@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 

答えて

2

最善のことは、VS2010付属しています"xsd.exe" toolを使用することです。これは、テーブルのXML記述からアセンブリまたはC#ソースファイルを作成できます。

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

これはADO.Netバインディングでのみ機能しますが、supports thoseです。

+0

ありがとう、私はそれを調べます。 – jlezard

関連する問題