开发者

Transfer a MySQL table into a F# matrix

I would like to transfer a SQL table (let say i. 2 columns : one containing users ID and one containing users age and ii. n rows) containing only integers into a F# matrix (same dimensions). I manage to do so with the following F# code, but I am convinced it is not the most efficient way to do so.

Indeed, the only way I found to dimensionate the F# matrix was to create 2 tables with a single value (number of rows and number of columns respectively) using MySQL and transfer these value into F#.

Is it possible to import a mySQL table into a F# matrix with a F# code which "recognize" the dimension of the matrix. Basically I would like a function which take a table address as an argument and return a matrix.

Here is my code :

#r "FSharp.PowerPack.dll"
#r "Microsoft.Office.Interop.Excel"
open System
open System.Data
open System.Data开发者_JAVA技巧.SqlClient
open Microsoft.Office.Interop
open Microsoft.FSharp.Math
open System.Collections.Generic

//Need of three types : User, number of rows and number of columns
type user = {
    ID :  int;
    Age : int;} 


type nbrRows = {NbreL : int ;} 

type nbrCol = {NbreC : int ;}

// I. Import the SQL data into F#
// I.1. Import the number of rows of the table into F#

  let NbrRows = seq { 

  use cnn = new SqlConnection(@"myconnection; database=MyDataBase; integrated security=true")
  use cmd1 = new SqlCommand("Select * from theTablesWhichContainsTheNumberOfRows", cnn)


  cnn.Open()
  use reader = cmd1.ExecuteReader()
  while reader.Read() do
    yield {
        NbreL = unbox(reader.["Expr1"])
    }
}

let NbrRowsList = NbrRows |> Seq.toList // convert the sequence into a List


// I.2. Same code to import the number of columns of the table

let NbrCol = seq { 

  use cnn = new SqlConnection(@"MyConnection; database=myDatabase; integrated security=true")
  use cmd1 = new SqlCommand("Select * from theTablesWhichContainsTheNumberOfColumns", cnn)


  cnn.Open()
  use reader = cmd1.ExecuteReader()
  while reader.Read() do
    yield {
        NbreC = unbox(reader.["Expr1"])
    }
}

let NbrColsList = NbrCol |> Seq.toList

// Initialisation of the Matrix

let matrixF = Matrix.create NbrRowsList.[0].NbreL NbrColsList.[0].NbreC  0.

//Transfer of the mySQL User table into F# through a sequence as previously

let GetUsers = seq { 

  use cnn = new SqlConnection(@"myConnection, database=myDatabase; integrated security=true")
  use cmd = new SqlCommand("Select * from tableUser ORDER BY ID", cnn)


  cnn.Open()
  use reader = cmd.ExecuteReader()
  while reader.Read() do
    yield {
        ID = unbox(reader.["ID"])
        Age = unbox(reader.["Age"])
    }
}

// Sequence to list

let UserDatabaseList = GetUsers |> Seq.toList

// Fill of the user matrix 

for i in 0 .. (NbrRowList.[0].NbreL - 1) do    
    matrixF.[0,i] <- UserDatabaseList.[i].ID |> float
    matrixF.[1,i] <- UserDatabaseList.[i].Age|> float 
matrixUsers


There are various ways to initialize matrix if you don't know its size in advance. For example Matrix.ofList takes a list of lists and it calculates the size automatically.

If you have just UserDatabaseList (which you can create withtout knowing the number of rows and columns), then you should be able to write:

Matrix.ofList
  [ // Create list containing rows from the database
    for row in UserDatabaseList do
      // For each row, return list of columns (float values)
      yield [ float row.ID; float row.Age ] ]

Aside - F# matrix is really useful mainly if you're going to do some matrix operations (and even then, it is not the most efficient option). If you're doing some data processing, then it may be easier to keep the data in an ordinary list. If you're doing some serious math, then you may want to check how to use Math.NET library from F#, which has more efficient matrix type.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜