开发者

Convert Sequence.Generate to Sequence Expression

I have the following code that uses Sequence objects to read data from a database table. V1 works correctly but since the Seq.generate function is deprecated I receive compiler warnings.

I tried to rerplace this code with V2 (below) but it does not work correctly - basically the reader is opened but only the first record is read - IOW - Read Next does not work correctly.

To avoid compilation errors/warnings I need to convert V1 code to use a sequence expression.

Any ideas on the correct approach here.

(BTW - This code is based on examples in Rob Pickering's Beginning F# book - (Data Access/ADO.NET Section).

********************** V1 - Sequence Approach - Deprecated ************************

// execute a command using the Seq.generate
let execCommand (connName: string) (cmdString: string) = 
    Seq.generate       
        // This function gets called to open a connection and create a reader
        (fun () -> openReader connName cmdString)
        // This function gets called to read a single item in
        // the enumerable for a reader/connection pair
        (fun reader -> readRow(reader))
        (fun reader -> reader.Dispose())

*********************** V2  Alternative - (Does not work) ***************************

let generateSequence connName cmdString =
       seq { // This function gets called to open a connection and
              //create a reader
              use reader = openReader connName cmdString
              // This function gets called to read a single item in
               // the enumerable for a reader/connection pair
              yiel开发者_开发百科d readRow(reader) }

// execute a command using the Seq.generate
let execCommand (connName: string) (cmdString: string) = 

    generateSequence connName cmdString


*****************************  Common Functions  **********************************

// Open a db connection
let openReader connName cmdString =
    let conn = openSQLConnection(connName)
    let cmd = conn.CreateCommand(CommandText=cmdString,
                                 CommandType = CommandType.Text)
    let reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)

// read a row from the data reader
let readRow (reader: #DbDataReader) =
    if reader.Read() then
        let dict = new Dictionary<string, obj>()
        for x in [ 0 .. (reader.FieldCount - 1) ] do
            dict.Add(reader.GetName(x), reader.[x])
        Some(dict)
    else
        None


You need to move around a few control structures to get this working.

let generateSequence connName cmdString =
    seq { 
        use reader = openReader connName cmdString
        while reader.Read () do
            yield readRow reader
        yield None
    }

let readRow (reader:#DbDataReader) =
    let dict = new Dictionary<string, obj>()
    for x in [0..(reader.FieldCount - 1)] do
        dict.Add (reader.GetName(x), reader.[x])
    Some dict


The only thing you left out is: while reader.Read() do

let generateSequence connName cmdString =
    seq { 
        use reader = openReader connName cmdString
        while reader.Read() do
            yield readRow reader 
    }
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜