3 people like it.

Dynamic (?) operator with null handling

An implementation of the ? operator that handles null

Dynamic operator

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
let (?) (reader:SqlDataReader) (name:string) : 'R =
  let typ = typeof<'R>
  if typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof<option<_>> then
    if reader.[name] = box DBNull.Value then 
      (box null) :?> 'R
    else typ.GetMethod("Some").Invoke(null, [| reader.[name] |]) :?> 'R
  else
    reader.[name] :?> 'R

Example

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
let cstr = "Data Source=.\\SQLExpress;Initial Catalog=Northwind;Integrated Security=True"

let printData() = 
  use conn = new SqlConnection(cstr)
  conn.Open()
  use cmd = new SqlCommand("SELECT * FROM [Products]", conn)

  printfn "10 Most Expensive Products\n=========================="
  use reader = cmd.ExecuteReader()
  while reader.Read() do
    let name = reader?ProductName
    let price = defaultArg reader?UnitPrice 0.0M
    printfn "%s (%A)" name price

printData()
val reader : SqlDataReader
type SqlDataReader =
  inherit DbDataReader
  member Close : unit -> unit
  member Depth : int
  member FieldCount : int
  member GetBoolean : i:int -> bool
  member GetByte : i:int -> byte
  member GetBytes : i:int * dataIndex:int64 * buffer:byte[] * bufferIndex:int * length:int -> int64
  member GetChar : i:int -> char
  member GetChars : i:int * dataIndex:int64 * buffer:char[] * bufferIndex:int * length:int -> int64
  member GetDataTypeName : i:int -> string
  member GetDateTime : i:int -> DateTime
  ...

Full name: System.Data.SqlClient.SqlDataReader
val name : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val typ : Type
val typeof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typeof
property Type.IsGenericType: bool
Type.GetGenericTypeDefinition() : Type
val typedefof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typedefof
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
type DBNull =
  member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
  member GetTypeCode : unit -> TypeCode
  member ToString : unit -> string + 1 overload
  static val Value : DBNull

Full name: System.DBNull
field DBNull.Value
Type.GetMethod(name: string) : Reflection.MethodInfo
Type.GetMethod(name: string, bindingAttr: Reflection.BindingFlags) : Reflection.MethodInfo
Type.GetMethod(name: string, types: Type []) : Reflection.MethodInfo
Type.GetMethod(name: string, types: Type [], modifiers: Reflection.ParameterModifier []) : Reflection.MethodInfo
Type.GetMethod(name: string, bindingAttr: Reflection.BindingFlags, binder: Reflection.Binder, types: Type [], modifiers: Reflection.ParameterModifier []) : Reflection.MethodInfo
Type.GetMethod(name: string, bindingAttr: Reflection.BindingFlags, binder: Reflection.Binder, callConvention: Reflection.CallingConventions, types: Type [], modifiers: Reflection.ParameterModifier []) : Reflection.MethodInfo
val cstr : string

Full name: Script.cstr
val printData : unit -> unit

Full name: Script.printData
val conn : SqlConnection
Multiple items
type SqlConnection =
  inherit DbConnection
  new : unit -> SqlConnection + 1 overload
  member BeginTransaction : unit -> SqlTransaction + 3 overloads
  member ChangeDatabase : database:string -> unit
  member Close : unit -> unit
  member ConnectionString : string with get, set
  member ConnectionTimeout : int
  member CreateCommand : unit -> SqlCommand
  member DataSource : string
  member Database : string
  member EnlistDistributedTransaction : transaction:ITransaction -> unit
  ...

Full name: System.Data.SqlClient.SqlConnection

--------------------
SqlConnection() : unit
SqlConnection(connectionString: string) : unit
SqlConnection.Open() : unit
val cmd : SqlCommand
Multiple items
type SqlCommand =
  inherit DbCommand
  new : unit -> SqlCommand + 3 overloads
  member BeginExecuteNonQuery : unit -> IAsyncResult + 1 overload
  member BeginExecuteReader : unit -> IAsyncResult + 3 overloads
  member BeginExecuteXmlReader : unit -> IAsyncResult + 1 overload
  member Cancel : unit -> unit
  member Clone : unit -> SqlCommand
  member CommandText : string with get, set
  member CommandTimeout : int with get, set
  member CommandType : CommandType with get, set
  member Connection : SqlConnection with get, set
  ...

Full name: System.Data.SqlClient.SqlCommand

--------------------
SqlCommand() : unit
SqlCommand(cmdText: string) : unit
SqlCommand(cmdText: string, connection: SqlConnection) : unit
SqlCommand(cmdText: string, connection: SqlConnection, transaction: SqlTransaction) : unit
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
SqlCommand.ExecuteReader() : SqlDataReader
SqlCommand.ExecuteReader(behavior: CommandBehavior) : SqlDataReader
SqlDataReader.Read() : bool
val price : decimal
val defaultArg : arg:'T option -> defaultValue:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.defaultArg

More information

Link:http://fssnip.net/hh
Posted:4 years ago
Author:Tomas Petricek
Tags: dynamic operator asd