Преобразовать последовательность. Генерировать в выражение последовательности - PullRequest
2 голосов
/ 09 апреля 2011

У меня есть следующий код, который использует объекты Sequence для чтения данных из таблицы базы данных. V1 работает правильно, но поскольку функция Seq.generate устарела, я получаю предупреждения компилятора.

Я пытался переместить этот код с V2 (ниже), но он работает неправильно - в основном читатель открыт, но читается только первая запись - IOW - Read Next не работать правильно.

Чтобы избежать ошибок / предупреждений компиляции, мне нужно преобразовать код V1 для использования выражения последовательности.

Любые идеи о правильном подходе здесь.

(Кстати - этот код основан на примерах из книги Роберта Пикеринга «Начало F #» - (Доступ к данным / Раздел ADO.NET).

********************** 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
              yield 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

Ответы [ 2 ]

1 голос
/ 09 апреля 2011

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

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
1 голос
/ 09 апреля 2011

Единственное, что вы оставили: while reader.Read() do

let generateSequence connName cmdString =
    seq { 
        use reader = openReader connName cmdString
        while reader.Read() do
            yield readRow reader 
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...