2011-01-07 25 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

相关问题