Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use SqlDataReader in F#

In C# I use sql scripts to add data into a List where T would be a class with fields/properties mapped to the sql script.

How could I do this in F#? This piece uses a stored procedure in the standard way.

using (conn)
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("dbo.query_here", conn))
    {
    cmd.CommandText = "dbo.query_here";
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandTimeout = 600;
    cmd.Parameters.Add(new SqlParameter("@x1", Convert.ToString(x)));
    cmd.Parameters.Add(new SqlParameter("@y1", y));
    cmd.Parameters.Add(new SqlParameter("@z1", z));
    SqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        MyListOfClasses.Add(new MyDataClass(reader.GetInt32(reader.GetOrdinal("x"))           
                                            reader.GetDouble(reader.GetOrdinal("y")),
                                            reader.GetDouble(reader.GetOrdinal("a")),
                                            reader.GetDouble(reader.GetOrdinal("b"))));
    }
    reader.Close();
}
conn.Close();

I realise F# is not quite as straight forward perhaps as this, but I need to get this data into F# lists in a similar way. Also would prefer suggestions that were not functional in nature and followed a similar pattern to C# code.

In a previous thread someone suggested using records, but still this was not in relation to SqlDataReader. It would be preferable to have a list of classes so I can use getters and setters on each item.

I should add before the inevitable comments of "why not just use C#". Well obviously I can use C#, but I am exploring possibilities of writing algorithms in F# and to do that I need to get my raw data from SQL Server.

like image 983
Richard Todd Avatar asked Sep 22 '12 11:09

Richard Todd


People also ask

What is the use of SqlDataReader?

The SqlDataReader is used to read a row of record at a time which is got using SqlCommand. It is read only, which means we can only read the record; it can not be edited. And also it is forward only, which means you can not go back to a previous row (record).

Do I need to close SqlDataReader?

You must explicitly call the Close method when you are through using the SqlDataReader to use the associated SqlConnection for any other purpose.

What is difference between SqlDataReader and SqlDataAdapter?

A SqlDataAdapter is typically used to fill a DataSet or DataTable and so you will have access to the data after your connection has been closed (disconnected access). The SqlDataReader is a fast forward-only and connected cursor which tends to be generally quicker than filling a DataSet/DataTable.

What does SqlDataReader return?

As explained earlier, the SqlDataReader returns data via a sequential stream. To read this data, you must pull data from a table row-by-row Once a row has been read, the previous row is no longer available.


1 Answers

If you would like to return results in F# list, list comprehension is suitable to use here. And with use keyword, you don't need to explicitly dispose objects.

use conn = (* Initialize sql connection here *)
conn.Open()
use cmd = new SqlCommand("dbo.query_here", conn)
cmd.CommandText <- "dbo.query_here"
cmd.CommandType <- System.Data.CommandType.StoredProcedure
cmd.CommandTimeout <- 600
cmd.Parameters.Add(new SqlParameter("@x1", Convert.ToString(x)))
cmd.Parameters.Add(new SqlParameter("@y1", y))
cmd.Parameters.Add(new SqlParameter("@z1", z))
use reader = cmd.ExecuteReader()
let results =
 [ while reader.Read() do
    yield new MyDataClass(reader.GetInt32(reader.GetOrdinal("x")),           
                          reader.GetDouble(reader.GetOrdinal("y")),
                          reader.GetDouble(reader.GetOrdinal("a")),
                          reader.GetDouble(reader.GetOrdinal("b"))) ]
like image 186
pad Avatar answered Sep 16 '22 19:09

pad