Hi Rob,

We'll be adding a few more samples over the next few days.

For now, here are some to get you going. This assumes

  • You have SQLEXPRESS installed
  • Nothwnd.mdf is in the same directory as your script
  • You've run SQLMETAL.EXE on that database to generate your database O/R mapping in northwnd.dll

Note the LINQ query support is in the F# power pack. It is labelled experimental because some advanced SQL concepts are not yet handled (e.g. left-outer-joins)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 

#nowarn "57"
#r @"System.Core.dll"
#r @"System.Data.Linq.dll"
#r @"FSharp.PowerPack.Linq.dll"
#r @"northwnd.dll"
open Microsoft.FSharp.Linq

let connString = @"AttachDBFileName='" + __SOURCE_DIRECTORY__ + @"\NORTHWND.MDF';Server='.\SQLEXPRESS';user instance=true;Integrated Security=SSPI;Connection Timeout=30" 

let db = new NORTHWND(connString)

// Add logging so we can see the SQL
db.Log <- System.Console.Out

// A simple select
query <@ seq { for c in db.Customers do 
                   yield (c.ContactName,c.Address) }  @>

// A simple select/take
query <@ seq { for c in db.Customers do 
                   yield (c.ContactName,c.Address) } 
         |> Seq.take 4 @>
                   
// A simple select/distinct
query <@ seq { for c in db.Customers do 
                   yield (c.ContactName,c.Address) } 
         |> Seq.distinct @>
                   
 
// A simple select/first
query <@ seq { for c in db.Customers do 
                   yield (c.ContactName,c.Address) } 
         |> Seq.hd @>

// A simple select/filter over two tables
query <@ seq { for c in db.Customers do 
                 for e in db.Employees do 
                     if c.Address.Contains("Jardim") && 
                        c.Address.Contains("rosas") then 
                           yield (e.LastName,c.ContactName) } @> 

// A simple select/filter over two tables, i.e. a join
query <@ seq { for c in db.Customers do 
                 for e in db.Employees do 
                  if c.ContactName = e.LastName then 
                    yield c.ContactName } @> 


// A query over three tables
query <@ seq { for p in db.Products do
                for c in db.Categories do
                 for s in db.Suppliers  do
                  yield c.CategoryName, p.ProductName, s.CompanyName } 
         |> Seq.length @>


// Using Nullable via reflected definitions
[<ReflectedDefinition>]
let (=?!) (x : System.Nullable<'a>) (y: 'a) = 
    x.HasValue && x.Value = y

query <@ seq { for p in db.Products do
                 for c in db.Categories do
                  for s in db.Suppliers  do
                    if p.CategoryID =?! c.CategoryID &&
                       p.SupplierID =?! s.SupplierID then 
                      yield c.CategoryName, p.ProductName, s.CompanyName } 
         |> Seq.length @>

query <@ seq { for p in db.Products do
                 if p.CategoryID =?! 1 then 
                     yield p.ProductName }  
         |> Seq.length @>

// A simple group_by.
query <@ Query.group_by
           (fun (c:Customers) -> c.Address.Length) 
           (seq { for c in db.Customers do yield c }) 
        |> Seq.length @> 

// A simple sort_by.
query <@ Seq.sort_by
           (fun (c:Customers) -> c.Address.Length) 
           (seq { for c in db.Customers do yield c }) 
        |> Seq.length @> 

// A simple 'exists'.
query <@ Seq.exists
           (fun (c:Customers) -> c.Address.Length > 10) 
           (seq { for c in db.Customers do yield c }) @> 


// A simple 'join'.
query <@ Query.join 
           (seq { for e in db.Employees do yield e }) 
           (seq { for c in db.Customers do yield c }) 
           (fun e -> e.Country) 
           (fun c -> c.Country) 
           (fun e c -> (e,c)) 
          |> Seq.length  @> 

// Another way to write the join
query <@ seq { for e in db.Employees do  
                   for c in db.Customers do 
                       if e.Country = c.Country then 
                           yield (e,c) } 
          |> Seq.length  @> 


// A simple group join
query <@ Query.group_join 
             (seq { for c in db.Employees do yield c }) 
             (seq { for c in db.Customers do yield c }) 
             (fun e -> e.Country) 
             (fun c -> c.Country) 
             (fun e cs -> (e,Seq.length cs)) 
          |> Seq.length  @> 
By on 9/4/2008 7:02 AM ()

I need with the following program. Line 5 is commented out (northwnd.dll does not reside on my computer); line 12 is causing error. I can't figured this problem.

#nowarn "57"
//#r @"System.Core.dll"
//#r @"System.Data.Linq.dll"
//#r @"FSharp.PowerPack.Linq.dll"
// Line 5 - #r @"northwnd.dll"
open Microsoft.FSharp.Linq

let connString = @"AttachDBFileName='" + __SOURCE_DIRECTORY__ + @"\NORTHWND.MDF';Server='.\SQLEXPRESS';user instance=true;Integrated Security=SSPI;Connection Timeout=30"

let db = new NORTHWND(connString) // Line 12 causing error.

// Add logging so we can see the SQL
db.Log <- System.Console.Out

// A simple select
query <@ seq { for c in db.Customers do
yield (c.ContactName,c.Address) } @>

By on 11/22/2008 8:58 AM ()

I posted a blog on Linq to SQL a few weeks ago that may help (i.e. [link:bloggemdano.blogspot.com]

By on 11/22/2008 11:50 AM ()

These samples look very cool - however when I paste this code into an F# script file "query" is underlined with a red squiggly and if I try to compile one of the query statements I get the message

error FS0039: The value or constructor 'query' is not defined.

I'm new to F# - am I doing something obviously wrong?

[ I'm running against SQL 2005 developer edtn on X64 - but have changed the connection string and appear to connect OK - eg "db.Customers;;" dumps values to the interactive window - other than each "query" there are no other red squiggly underlines ]

Cheers,
Tony.

By on 11/5/2008 11:20 AM ()

Hi,

In case anyone else is similarly confused as I was ... after spending a few minutes with Reflector I replaced ...

"query"

... with ...

Query.query

... and all seems well.

Regards,

Tony.

By on 11/6/2008 3:42 AM ()

Great! Thanks very much, Don. I'll definitely try it out.

Cheers!
Rob

By on 9/4/2008 4:07 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper