簡體   English   中英

在F#中使用SqlDataReader

[英]Use SqlDataReader in 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無關。 最好有一個類列表,這樣我就可以在每個項目上使用getter和setter方法。

我應該在不可避免的注釋之前加上“為什么不僅僅使用C#”。 顯然,我可以使用C#,但是我正在探索用F#編寫算法的可能性,為此,我需要從SQL Server中獲取原始數據。

如果要在F#列表中返回results ,則列表理解適用於此。 使用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"))) ]

使用F#動態運算符,使用普通的舊ADO.NET處理數據庫實際上可以很好地完成工作? 我寫了一篇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教程的鏈接:

你可以看一下

鏈接: 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.

未經測試的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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM