Автоматическая генерация типа записи на основе таблиц базы данных MySql для использования в FSharpDAL - PullRequest
1 голос
/ 07 января 2011

Я использовал FSharpDAL для чтения таблиц данных в базе данных Mysql.Это хорошо работает, но вы должны указать тип записи.Что означает, что для каждой таблицы вы должны определить тип записи.Я хотел бы получить тип записи, сгенерированный автоматически из схемы таблицы.Также, когда столбец таблицы обнуляется, я бы хотел, чтобы поле записи coresponding было типом параметра.

Есть ли что-нибудь, что может это сделать?(пока не появятся провайдеры типов)

Большое спасибо

Примечание. Я пытался сделать свою версию (которая компилирует модуль с типами записей), кажется, работает, но уродливо:@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

1 Ответ

2 голосов
/ 08 января 2011

Лучшее, что я могу придумать, - это использовать "xsd.exe" инструмент , который поставляется с VS2010.Он может создать исходный файл Assembly или C # из XML-описания таблицы.

Само XML-описание можно экспортировать из WriteXmlSchema метода класса DataSet.

Это работает только с привязками ADO.Net, но MySQL поддерживает эти .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...