Lightweight ‘O/R Mapping’ in F# Interactive

by Dean 26. April 2010 21:15

I’ve been playing a lot with F# lately, particularly in the area of financial option modelling, which requires quite a lot of number crunching – a perfect scenario for tinkering around in F# interactive.

However, I need to get data out of my data store, and use it to create collections of records, that represent the data that I need.

This was becoming a little cumbersome, so I thought I’d create a little ORM function to do the trick

open System.Data.SqlClient
open Microsoft.FSharp.Reflection
 
let BuildData<'T> (connection:string, command:string) = 
    let conn = new SqlConnection(connection)
    let comm = new SqlCommand(command,conn)
    let recordType = typeof<'T>
    let fieldCount = FSharpType.GetRecordFields(recordType).Length
    conn.Open()
    let db = comm.ExecuteReader()
    let rec populate (reader:SqlDataReader) (l:'T list) = 
        match reader.Read() with
        | false -> l
        | _ -> 
            let vals = Array.create<obj> fieldCount null
            ignore(reader.GetValues(vals))
            let dataObj = FSharpValue.MakeRecord(recordType,vals) :?> 'T 
            let x = dataObj::l
            populate reader x
    let  data = populate db []
    conn.Close()
    data

run the above in interactive, and you’ll get

val BuildData : string * string -> 'T list

now lets give it a spin

 

type pricedata = { Price : Decimal; Symbol : String; PriceDate : DateTime }
let conn = "Data Source=DEAN-PC\SQLEXPRESS;Initial Catalog=StockData;Integrated Security=SSPI"
let comm = "select price, symbol, pricedate from symboldata where symbol = 'AA'"
let data = BuildData<pricedata>(conn,comm)

so we now have a strongly-typed collection, ready for pumping into our financial modelling functions

or alternatively, you could display the data in a grid :-

open System.Windows.Forms
 
let grid data =
    let form = new System.Windows.Forms.Form(Visible=true,TopMost=true)
    let g = new System.Windows.Forms.DataGrid(Dock = DockStyle.Fill, Visible=true)
    g.DataSource <- List.toArray data
    form.Controls.Add(g) 
 
grid data

and the result is like this

stockdata

Tags: , , ,

F# | DataBinding

F# And MVVM – A Simple ViewModel

by Dean 12. April 2010 20:51

For many years, OOP abstractions and design patterns have been the cornerstones of my development methodology as a senior C# developer in investment banking.

However, over the last year or so I have taken quite a shine to Microsoft’s new FP language (F#), not just because purely functional program code is concise powerful and elegant, but because the eclectic mix of functional and OOP paradigms in F# enable me to develop better, faster, stronger and more maintainable applications.

In investment banking, the business has been changing fast, and being able to get production quality WPF apps onto the trader desks has been a big priority, and with F# I find myself more able to meet that challenge.

The WPF design pattern ‘du jour’ is MVVM. Anyone who’s serious about enterprise-strength development in WPF would have come across this pattern and probably have used it at some point in the recent past.

Detailed below is a very basic implementation where :-

  1. There is a WPF project that contains only Views
  2. There is a C# ‘model’ project that contains only the generated classes from SqlMetal (for Linq to SQL)
  3. The is an F# code library project that contains my ViewModel

The F# ViewModel is a very simple one, but it covers all the main bases:-

  1. It has a generic ICommand implementation for command binding
  2. It implements INotifyPropertyChanged for change notifications
  3. It has Data for binding

So here it is

#light
module FSharpMVVM
 
open System
open System.Windows.Input
open System.Data.SqlClient
open System.ComponentModel
open FsMVVM.DAL
 
// below is our Linq-SQL data context, created via SqlMetal and in a separate
// C# project - as SqlMetal doesnt generate F# yet *)
 
let ctx = new DataClassesDataContext()
 
// an implemnentation of a generic ICommand, that takes two functions
// one to see if the command can be executed, and one to execute the command 
 
type FuncCommand (canExec:(obj -> bool),doExec:(obj -> unit)) =
    let cecEvent = new DelegateEvent<EventHandler>()
    interface ICommand with
        [<CLIEvent>]
        member x.CanExecuteChanged = cecEvent.Publish
        member x.CanExecute arg = canExec(arg)
        member x.Execute arg = doExec(arg)
 
// Our ViewModel is below
 
type MainViewModel() =  
    let mutable prods = Seq.toList ctx.Products 
    let a =  new PropertyChangedEventArgs("ProductData")
    let propChangedEvent = new DelegateEvent<PropertyChangedEventHandler>()
    interface INotifyPropertyChanged with 
        [<CLIEvent>]
        member x.PropertyChanged = propChangedEvent.Publish
    member x.ProductData with get() = prods
    member x.FilterCommand = 
        new FuncCommand(
            (fun d -> not(Seq.isEmpty ctx.Products)),
            (fun e -> prods <- Seq.toList ctx.Products 
                    |> List.filter (
                        fun p -> p.ProductName.Contains(e.ToString()));
                        propChangedEvent.Trigger([| box x; box a|])))

 

and below is the simple View (XAML)

 

<Window x:Class="FsMVVM.WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Margin="5">
            <TextBox Name="searchText" MinWidth="100" />
            <Button Content="Search" Command="{Binding FilterCommand}" 
                    CommandParameter="{Binding ElementName=searchText, Path=Text}" />
        </StackPanel>
        <ListView ItemsSource="{Binding ProductData}" Grid.Row="1">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Name" DisplayMemberBinding="{Binding ProductName}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

 

and finally, its wired up in the code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new FSharpMVVM.MainViewModel();
    }
}

and that's all it takes

Now, I know that there isnt a great deal of functional programming in this example, but now I have the building blocks for a more complex ViewModel, that will no doubt include a great deal more FP before it is finished

 

Dean

Tags: ,

DataBinding | F# | MVVM

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010 Dean Chalk's Blog