Question

I have the following F# code. The function getARow returns (string * string * string) option. In the main function, I need to extract column values and assign them to a, b, c respectively. How to implement it? (Newbie question)

And The function may return null if there is no row found? How to handle it if getARow returns null?

open System
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
open System.Net
open System.IO
open FSharp.Data

type dbSchema = SqlDataConnection<"Data Source=Svr;Initial Catalog=DB;Integrated Security=SSPI;"> 
//, LocalSchemaFile = "Schema.dbml", ForceUpdate = false > 

let getARow =
    let db = dbSchema.GetDataContext()
    db.DataContext.Log <- System.Console.Out
    let query = query { 
        for row in db.Table1 do 
        where (row.SiteID = 1) 
        select (Some(row.Col1, row.Col2, row.Col2)) // All Colx are strings
        headOrDefault // May return null
        }
    query 

[<EntryPoint>]
let main argv = 
    let aRow = getARow
    printfn "%A" aRow 

    let a,b,c = match aRow with
    | ........ // How to let a = Col1, b = Col2 and c = Col3?
    | None -> failwith "Cannot find a row" // Null?
    0
Was it helpful?

Solution

To extract values from an option type (no matter what it contains), you need to use the Some <...> pattern where <...> is a nested pattern that is can give name to the value (if you want a single variable containing the tuple) or decompose it further (if you want three separate variables):

let a,b,c = 
  match aRow with
  | Some(a, b, c) -> a, b, c
  | None -> failwith "Cannot find a row"

Alternatively, you can just use the built-in Option.get function:

let a,b,c = Option.get aRow

Your code relies on a trick - that headOrDefault returns null if there is no row - which will work, because null is the internal representation of None. But you could also use an extension that adds headOrNone to make the code a bit nicer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top