hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

FLinq samples for CTP?

Last post 11-22-2008, 11:50 by dmohl. 6 replies.
Sort Posts: Previous Next
  •  09-04-2008, 0:09 6868

    FLinq samples for CTP?

    Are there any samples of FLinq that work with the new CTP?  The only FLinq samples I have yet found, in the prior release, were actually broken in that release.  It seems that the CTP ships with no samples at all, and the 0.1 samples on MSDN don't contain any actual examples of working with FLinq.

    Can it really be the case that there is no officially supported sample demonstrating the FLinq expression tree stuff working with sample Northwind?  When will this be addressed?  FLinq is very cool, but without an officially supported sample it's hard to know (or personally verify) how stable the features are expected to be.

    Cheers,

    Rob

  •  09-04-2008, 7:02 6880 in reply to 6868

    Re: FLinq samples for CTP?

    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)



    #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  @>

  •  09-04-2008, 16:07 6905 in reply to 6880

    Re: FLinq samples for CTP?

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

    Cheers!
    Rob

  •  11-05-2008, 11:20 7624 in reply to 6880

    Re: FLinq samples for CTP?

    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.


  •  11-06-2008, 3:42 7640 in reply to 7624

    Re: FLinq samples for CTP?

    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.

  •  11-22-2008, 8:58 7916 in reply to 6880

    Re: FLinq samples for CTP?

    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) }  @>

  •  11-22-2008, 11:50 7917 in reply to 7916

    Re: FLinq samples for CTP?

    I posted a blog on Linq to SQL a few weeks ago that may help (i.e. http://bloggemdano.blogspot.com/2008/11/linq-to-sql-in-f.html).




    Daniel Mohl
    Blog: http://bloggemdano.blogspot.com/
    Twitter: @dmohl
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems