2011-01-07 66 views
1

我一直在使用FSharpDAL來讀取Mysql數據庫中的數據表。它運作良好,但您必須提供記錄類型。這意味着你必須爲每個表定義一個記錄類型。我想從表模式中自動生成記錄類型。另外,當表列可以爲空時,我想將相應的記錄字段設置爲選項類型。基於MySql數據庫表的自動生成記錄類型,用於FSharpDAL

有沒有可以做到這一點的東西? (直到型供應商到達)

非常感謝

注意我試圖做我的版本(編譯模塊與記錄類型),似乎工作,但它的醜陋:(感謝@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描述中創建一個Assembly或C#源文件。

XML描述本身可以從DataSet類的WriteXmlSchema method中導出。

這隻適用於ADO.Net綁定,但MySQL supports those

+0

謝謝,我會研究它。 – jlezard 2011-01-08 15:21:03

相關問題