Используйте SqlDataReader в F #

В C # я использую сценарии sql для добавления данных в список, где T будет классом с полями / свойствами, сопоставленными со сценарием sql.

Как я мог сделать это в F #? Эта часть использует хранимую процедуру стандартным способом.

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();

Я понимаю, что F #, возможно, не так прост, как этот, но мне нужно аналогичным образом поместить эти данные в списки F #. Также предпочел бы предложения, которые не были функциональными по своей природе и следовали примеру, подобному коду C #.

В предыдущем потоке кто-то предлагал использовать записи, но это не было связано с SqlDataReader. Было бы предпочтительнее иметь список классов, чтобы я мог использовать методы получения и установки для каждого элемента.

Я должен добавить перед неизбежными комментариями & quot; почему бы просто не использовать C # & quot ;. Конечно, я могу использовать C #, но я изучаю возможности написания алгоритмов на F # и для этого мне нужно получить исходные данные из SQL Server.

Ответы на вопрос(4)

Непроверенный перевод на F #

use conn = ???
conn.Open()
using new SqlCommand("dbo.query_here", conn)(fun cmd ->

    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))
    let reader = cmd.ExecuteReader()
    while (reader.Read()) do
        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()
MyListOfClasses.ToArray() |> List.ofArray
 22 сент. 2012 г., 22:33
@RichardTodd - исправлено
 Richard Todd22 сент. 2012 г., 14:32
вывод должен быть неизменным списком F #, иначе я бы просто использовал C #
 Richard Todd23 сент. 2012 г., 03:04
Спасибо, как и простота тоже. Я отвечал, но в приведенном выше примере используется список компов, что довольно приятно.

Вы можете прочитать это

Ссылка на сайт :http://www.codeproject.com/Articles/95656/Using-a-DataRader-like-a-List-in-F

let rdr = cmd.ExecuteReader()

rdr
|> SomeRecord.asSeq                     // project datareader into seq<SomeRecord>
|> Seq.sumBy (fun r-> r.val1 * r.val2)  // now you can use all the Seq operators 
                                        // that everybody knows.
Решение Вопроса

Если вы хотите вернутьсяresults в списке F # здесь можно использовать понимание списка. И сuse Ключевое слово, вам не нужно явно располагать объекты.

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"))) ]
 Richard Todd23 сент. 2012 г., 03:00
Это ответ, который я хотел. Спасибо, сэр. Я знаю, что мне не нужно избавляться, привычка от VBA, я думаю :(.

Работать с базами данных, используя старый ADO.NET, довольно просто, если использовать динамический оператор F #?, Я написалСтатья MSDN, которая реализует помощника это позволяет вам написать что-то вроде:

let myListOfClasses = 
  [ let db = new DynamicDatabase(connectionString)
    let rows = db.Query?query_here(string x, y, z)
    for r in rows do 
      yield MyDataClass(row?x, row?y, row?a, row?b) ]

Это использует динамический оператор вызова? вызвать хранимую процедуру (db.Query?query_here). Когда вы вызываете его, вы можете задать ему параметры, как если бы это был обычный вызов функции (он добавит их в качестве параметров SQL). Тогда вы также можете использоватьrow?x читать свойства - это выводит тип из типаMyDataClass аргументы, поэтому при условии, что они совпадают, вам не нужно писать преобразования типов самостоятельно.

Вот ссылки на учебник MSDN, в котором обсуждается это:

How to: Dynamically Invoke a Stored Procedure Step 1: Create a Database and Show the Poll Options Step 2: Implement Voting for an Option
 Richard Todd22 сент. 2012 г., 14:31
Мне это нравится, но это слишком сложно для простой задачи, которую я пытаюсь сделать, есть ли не просто очень простой способ использования метода C #, но вместо List (ResizeArray) мы используем F # list? Или конвертировать из одного в другое?
 26 мая 2017 г., 15:46
Спасибо, я думаю, это может быть полезно для меня вместе с этим другимanswer
 23 сент. 2012 г., 22:44
@RichardTodd Да, согласился - для одной задачи это слишком сложно. Вы все еще можете определить(?) оператор для доступа к свойствам изSqlDataReader - это довольно просто. Я не уверен, что вы спрашиваете о списках? (Вы можете получить список F # из любогоIEnumerable с помощьюList.ofSeq...)

Ваш ответ на вопрос