8

C# では、SQL スクリプトを使用して List にデータを追加します。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 とは関係ありませんでした。各アイテムでゲッターとセッターを使用できるように、クラスのリストを用意することをお勧めします。

「なぜC#を使わないのか」という避けられないコメントの前に追加する必要があります。明らかに C# を使用できますが、F# でアルゴリズムを記述する可能性を探っています。そのためには、SQL Server から生データを取得する必要があります。

4

4 に答える 4

12

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"))) ]
于 2012-09-22T17:38:59.803 に答える
8

単純な古い 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 チュートリアルへのリンクを次に示します。

于 2012-09-22T11:59:48.247 に答える
5

あなたはこれを読むことができます

リンク: 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.
于 2012-09-22T11:42:07.953 に答える
3

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
于 2012-09-22T11:49:34.423 に答える