2011-04-09 3 views
2

J'ai le code suivant qui utilise des objets Sequence pour lire les données d'une table de base de données. V1 fonctionne correctement mais comme la fonction Seq.generate est obsolète, je reçois des avertissements du compilateur.Convert Sequence.Generate en séquence d'expression

J'ai essayé de rerplace ce code avec V2 (ci-dessous), mais il ne fonctionne pas correctement - essentiellement le lecteur est ouvert, mais seul le premier enregistrement est lu - OIEau - Lire la suite ne pas correctement travail.

Pour éviter les erreurs/avertissements de compilation, j'ai besoin de convertir le code V1 pour utiliser une expression de séquence.

Toutes les idées sur la bonne approche ici.

(BTW - Ce code est basé sur des exemples en début de Rob Pickering F # livre - (accès aux données/Section 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 

Répondre

1

Vous devez déplacer quelques structures de contrôle pour obtenir ce travail.

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

La seule chose que vous avez oublié est la suivante:. while reader.Read() do

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