anchor.diff:              assert (rank = ResultRank.Sequence)
               box xs 
               
  -    let internal asyncExecuteSeq<'TItem> (rank, rowMapper) (cmd, getReaderBehavior, parameters) = 
  +    static member AsyncExecuteSeq<'TItem> (rank, rowMapper) (cmd, getReaderBehavior, parameters) = 
           let xs = 
               async {
  -                let! reader = asyncExecuteReader(cmd, getReaderBehavior, parameters)
  +                let! reader = SqlCommand<_>.AsyncExecuteReader(cmd, getReaderBehavior, parameters)
                   return reader |> Seq.ofReader<'TItem> rowMapper
               }
   
  
positive.code:             assert (rank = ResultRank.Sequence)
              box xs 
  
      let internal executeNonQuery(cmd, _, parameters) = 
          setParameters cmd parameters  
          use openedConnection = cmd.Connection.UseLocally()
          cmd.ExecuteNonQuery() 
  
      let internal asyncExecuteNonQuery(cmd, _, parameters) = 
          setParameters cmd parameters  
          async {         
              use openedConnection = cmd.Connection.UseLocally()
              return! cmd.AsyncExecuteNonQuery() 
          }
  
      let getExecuteImplementations<'TItem>(cmd, resultType, rank, rowMapping) = 
          match resultType with
          | ResultType.Records | ResultType.Tuples ->
              if box rowMapping = null
              then
                  executeNonQuery >> box, asyncExecuteNonQuery >> box
              else
                  executeSeq<'TItem> (rank, rowMapping) >> box, asyncExecuteSeq<'TItem> (rank, rowMapping) >> box
          | ResultType.DataTable ->
              executeDataTable >> box, asyncExecuteDataTable >> box
          | ResultType.DataReader -> 
              executeReader >> box, asyncExecuteReader >> box
          | unexpected -> failwithf "Unexpected ResultType value: %O" unexpected
  
  type Connection =
      | Literal of string
      | NameInConfig of string
      | Transaction of SqlTransaction
  
  type SqlCommand<'TItem> (connection, sqlStatement, isStoredProcedure, parameters, resultType, rank, rowMapping: RowMapping) = 
  
      let cmd = new SqlCommand(sqlStatement, CommandType = if isStoredProcedure then CommandType.StoredProcedure else CommandType.Text)
      do 
          match connection with
          | Literal value -> 
              cmd.Connection <- new SqlConnection(value)
          | NameInConfig name ->
              let connStr = Configuration.GetConnectionStringAtRunTime name
              cmd.Connection <- new SqlConnection(connStr)
          | Transaction t ->
               cmd.Connection <- t.Connection
               cmd.Transaction <- t
  
      do
          cmd.Parameters.AddRange( parameters)
  
      let getReaderBehavior() = 
          seq {
              yield CommandBehavior.SingleResult
  
              if cmd.Connection.State <> ConnectionState.Open 
              then
                  cmd.Connection.Open() 
                  yield CommandBehavior.CloseConnection
  
              if rank = ResultRank.SingleRow then yield CommandBehavior.SingleRow 
  
              if resultType = ResultType.DataTable then yield CommandBehavior.KeyInfo
          }
          |> Seq.reduce (|||) 
  
      let execute, asyncExecute = SqlCommand.getExecuteImplementations<'TItem>(cmd, resultType, rank, rowMapping)
  
      member this.AsSqlCommand() = 
          let clone = new SqlCommand(cmd.CommandText, new SqlConnection(cmd.Connection.ConnectionString), CommandType = cmd.CommandType)
          clone.Parameters.AddRange <| [| for p in cmd.Parameters -> SqlParameter(p.ParameterName, p.SqlDbType) |]
          clone
  
      interface ISqlCommand with
  
          member this.Execute parameters = execute(cmd, getReaderBehavior, parameters)
          member this.AsyncExecute parameters = asyncExecute(cmd, getReaderBehavior, parameters)
  
          member this.ToTraceString parameters =  
              let clone = this.AsSqlCommand()
              SqlCommand.setParameters clone parameters  
              let parameterDefinition (p : SqlParameter) =
                  if p.Size <> 0 then
                      sprintf "%s %A(%d)" p.ParameterName p.SqlDbType p.Size
                  else
                      sprintf "%s %A" p.ParameterName p.SqlDbType 
              seq {
                yield sprintf "exec sp_executesql N'%s'" clone.CommandText
                
                yield clone.Parameters
                      |> Seq.cast<SqlParameter> 
                      |> Seq.map parameterDefinition
                      |> String.concat ","
                      |> sprintf "N'%s'" 
                yield parameters
                      |> Seq.map(fun (name,value) -> sprintf "%s='%O'" name value) 
                      |> String.concat ","
              } |> String.concat "," //Using string.concat to handle annoying case with no parameters
  
          member this.Raw = cmd
              
      interface IDisposable with
          member this.Dispose() =
              cmd.Dispose()
  
  
negative.code:     | SingleRow = 1
      | ScalarValue = 2
  
  type Connection =
      | Literal of string
      | NameInConfig of string
      | Transaction of SqlTransaction
  
  type SqlCommand<'TItem1> (connection, sqlStatement, isStoredProcedure, parameters, resultType, rank, rowMapping: RowMapping) = 
  
      let cmd = new SqlCommand(sqlStatement, CommandType = if isStoredProcedure then CommandType.StoredProcedure else CommandType.Text)
      do 
          match connection with
          | Literal value -> 
              cmd.Connection <- new SqlConnection(value)
          | NameInConfig name ->
              let connStr = Configuration.GetConnectionStringAtRunTime name
              cmd.Connection <- new SqlConnection(connStr)
          | Transaction t ->
               cmd.Connection <- t.Connection
               cmd.Transaction <- t
  
      do
          cmd.Parameters.AddRange( parameters)
  
      let getReaderBehavior() = 
          seq {
              yield CommandBehavior.SingleResult
  
              if cmd.Connection.State <> ConnectionState.Open 
              then
                  cmd.Connection.Open() 
                  yield CommandBehavior.CloseConnection
  
              if rank = ResultRank.SingleRow then yield CommandBehavior.SingleRow 
  
              if resultType = ResultType.DataTable then yield CommandBehavior.KeyInfo
          }
          |> Seq.reduce (|||) 
  
      let execute, asyncExecute = SqlCommand<_>.GetExecuteImplementations(cmd, resultType, rank, rowMapping)
  
      member this.AsSqlCommand() = 
          let clone = new SqlCommand(cmd.CommandText, new SqlConnection(cmd.Connection.ConnectionString), CommandType = cmd.CommandType)
          clone.Parameters.AddRange <| [| for p in cmd.Parameters -> SqlParameter(p.ParameterName, p.SqlDbType) |]
          clone
  
      interface ISqlCommand with
  
          member this.Execute parameters = execute(cmd, getReaderBehavior, parameters)
          member this.AsyncExecute parameters = asyncExecute(cmd, getReaderBehavior, parameters)
  
          member this.ToTraceString parameters =  
              let clone = this.AsSqlCommand()
              SqlCommand<_>.SetParameters(clone, parameters)  
              let parameterDefinition (p : SqlParameter) =
                  if p.Size <> 0 then
                      sprintf "%s %A(%d)" p.ParameterName p.SqlDbType p.Size
                  else
                      sprintf "%s %A" p.ParameterName p.SqlDbType 
              seq {
                yield sprintf "exec sp_executesql N'%s'" clone.CommandText
                
                yield clone.Parameters
                      |> Seq.cast<SqlParameter> 
                      |> Seq.map parameterDefinition
                      |> String.concat ","
                      |> sprintf "N'%s'" 
                yield parameters
                      |> Seq.map(fun (name,value) -> sprintf "%s='%O'" name value) 
                      |> String.concat ","
              } |> String.concat "," //Using string.concat to handle annoying case with no parameters
  
          member this.Raw = cmd
              
      interface IDisposable with
          member this.Dispose() =
              cmd.Dispose()
  
  //Execute/AsyncExecute versions
      static member SetParameters(cmd: SqlCommand, parameters: (string * obj)[]) = 
          for name, value in parameters do
              
              let p = cmd.Parameters.[name]            
  