F#Beginner:从服务器检索数据数组

Pau*_*han 6 mysql database f#

我正试图从MySQL数据库中获取数据.

方法2 - 应用/地图样式

我正在使用MySQL ADO Reference来尝试构建这个系统.特别是,例子发现于21.2.3.1.7.

(使用伪代码)

let table = build_sequence(query.read)
Run Code Online (Sandbox Code Playgroud)

其中query.read返回表中的一行(或者更确切地说,恰好是表中一行的元素列表).表变量是一个列表列表,表示从查询返回的表.

我盯着下面给出的代码,它的语法是我的头脑,我很害怕.

方法1 - 循环.

问题1:它不够优雅,需要一个可变的.

问题2:根据我之前使用Prolog和Lisp的经验,这感觉不对.要做到这一点,必须有更多...... 功能性的方法.

我不知道从哪里开始.评论和想法?

let reader : MySql.Data.MySqlClient.MySqlDataReader = command.ExecuteReader()

let arr = []

let mutable rowIter = 0
let readingLoop() =
    while(reader.Read()) do
        rowIter = rowIter + 1
        for i = 0 to reader.FieldCount do

            //set arr[someiterator, i] = reader.GetValue[i].ToString())
Run Code Online (Sandbox Code Playgroud)

sim*_*nuk 10

Seq类型有一个简洁的函数来处理名为generate_using的数据库游标(参见F#ManualF#基础中的数据访问章节).这是一个更高阶的函数,它接受一个函数来打开游标,另一个函数(重复调用)来处理来自游标的记录.以下是一些使用generate_using执行sql查询的代码:

let openConnection (connectionName : string) =
    let connectionSetting = ConfigurationManager.ConnectionStrings.Item(connectionName)
    let connectionString = connectionSetting.ConnectionString
    let connection = new OracleConnection(connectionString)
    connection.Open()
    connection

let generator<'a> (reader : IDataReader) =
    if reader.Read() then
        let t = typeof<'a>
        let props = t.GetProperties()
        let types = props
                    |> Seq.map (fun x -> x.PropertyType)
                    |> Seq.to_array
        let cstr = t.GetConstructor(types)
        let values = Array.create reader.FieldCount (new obj())
        reader.GetValues(values) |> ignore
        let values = values
                     |> Array.map (fun x -> match x with | :? DBNull -> null | _ -> x)
        Some (cstr.Invoke(values) :?> 'a)
    else
        None

let executeSqlReader<'a> (connectionName : string) (sql : string) : 'a list =        
    let connection = openConnection connectionName

    let opener() = 
        let command = connection.CreateCommand(CommandText = sql, CommandType = CommandType.Text)
        command.ExecuteReader()

    let result = Seq.to_list(Seq.generate_using opener generator)        

    connection.Close()
    connection.Dispose()
    result
Run Code Online (Sandbox Code Playgroud)

例如,要列出Oracle数据库中的所有表,我们需要定义列定义类型并调用executeSqlReader,如下所示:

type ColumnDefinition = {
    TableName : string;
    ColumnName : string;
    DataType : string;
    DataLength : decimal;                
}

let tableList = executeSqlReader<ColumnDefinition>
    "MyDatabase"
    "SELECT t.table_name, column_name, data_type, data_length FROM USER_TABLES t, USER_TAB_COLUMNS c where t.TABLE_NAME = c.table_name order by t.table_name, c.COLUMN_NAME"
Run Code Online (Sandbox Code Playgroud)