Channels ▼
RSS

JVM Languages

More Information-Rich Programming with F#


If you take a look at the XML, it is easy to see that the WsdlService type provider can gather the necessary information to infer types:

<service xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app" xml:base="http://live.ineta.org/InetaLiveService.svc/">
  <workspace>
    <atom:title>Default</atom:title>
    <collection href="LivePresentations">
      <atom:title>LivePresentations</atom:title>
    </collection>
    <collection href="LiveVideos">
      <atom:title>LiveVideos</atom:title>
    </collection>
    <collection href="LiveAuthors">
      <atom:title>LiveAuthors</atom:title>
    </collection>
    <collection href="LiveGroups">
      <atom:title>LiveGroups</atom:title>
    </collection>
    <collection href="LiveTags">
      <atom:title>LiveTags</atom:title>
    </collection>
  </workspace>
</service>

It is easy to write queries and check the results in a browser. For example, to retrieve the first live presentation that includes "Blend" in its abstract, I just need to enter the following URL (see Figure 7):

http://live.ineta.org/InetaLiveService.svc/LivePresentations()?$filter=substringof('Blend',Abstract)&$top=1

[Click image to view at full size]
Figure 7: The XML with the results of an OData query that retrieves the first presentation that includes "Blend" in its abstract.

As you can see in the following lines, the result includes useful type information for the type provider:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<feed xml:base="http://live.ineta.org/InetaLiveService.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">LivePresentations</title>
  <id>http://live.ineta.org/InetaLiveService.svc/LivePresentations</id>
  <updated>2012-11-29T17:25:42Z</updated>
  <link rel="self" title="LivePresentations" href="LivePresentations" />
  <entry>
    <id>http://live.ineta.org/InetaLiveService.svc/LivePresentations(1)</id>
    <title type="text"></title>
    <updated>2012-11-29T17:25:42Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="LivePresentation" href="LivePresentations(1)" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/LiveVideos" type="application/atom+xml;type=feed" title="LiveVideos" href="LivePresentations(1)/LiveVideos" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/LiveTags" type="application/atom+xml;type=feed" title="LiveTags" href="LivePresentations(1)/LiveTags" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/LiveAuthors" type="application/atom+xml;type=feed" title="LiveAuthors" href="LivePresentations(1)/LiveAuthors" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/LiveGroup" type="application/atom+xml;type=entry" title="LiveGroup" href="LivePresentations(1)/LiveGroup" />
    <category term="INETALivePublicModel.LivePresentation" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:PresentationID m:type="Edm.Int32">1</d:PresentationID>
        <d:Title>Expression Blend 4</d:Title>
        <d:DeliveredOn m:type="Edm.DateTime">2010-05-08T00:00:00</d:DeliveredOn>
        <d:Abstract>Blend 4 - Let's get started with Blend Come join us to learn the Blend UI and see how far Blend can take your XAML projects. We will cover the controls and settings within Blend to give you a basic foundation to move forward from. Although many things will be touched upon in order to show off the gui controls, this talk is not a deep dive into XAML, building complex controls, or live data integration. It is a good foundation for those discussions to follow.</d:Abstract>
        <d:GroupID m:type="Edm.Int32">1</d:GroupID>
      </m:properties>
    </content>
  </entry>
</feed>

Instead of entering OData queries in the browser, you can take advantage of the ODataService type provider to discover the data structure as you retrieve it. The following lines show the result of a quick FSI session that uses the ODataService type provider to connect to the INETA OData service and retrieves the first LivePresentation.

Microsoft (R) F# Interactive version 11.0.50727.1
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> #r "System.Data"
#r "System.Data.Linq"
#r "FSharp.Data.TypeProviders"
open Microsoft.FSharp.Data.TypeProviders
;;
 
--> Referenced 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll'
 
--> Referenced 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.Linq.dll'
 
--> Referenced 'C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\3.0\Runtime\v4.0\Type Providers\FSharp.Data.TypeProviders.dll'
> [<Literal>]
let InetaServiceAddress = "http://live.ineta.org/InetaLiveService.svc/"
   
type InetaCatalog = ODataService<InetaServiceAddress>
let inetaDatabase = InetaCatalog.GetDataContext()
;;

 
val InetaServiceAddress : string =
  "http://live.ineta.org/InetaLiveService.svc/"
type InetaCatalog =
  class
    static member GetDataContext : unit -> InetaCatalog.ServiceTypes.SimpleDataContextTypes.INETALivePublic
     + 1 overload
    nested type ServiceTypes
  end
val inetaDatabase :
  InetaCatalog.ServiceTypes.SimpleDataContextTypes.INETALivePublic
> let onePresentation = Seq.head inetaDatabase.LivePresentations
;;
val onePresentation : InetaCatalog.ServiceTypes.LivePresentation
> onePresentation
;;
val it : InetaCatalog.ServiceTypes.LivePresentation =
  LivePresentation
    {Abstract = "Blend 4 - Let's get started with Blend Come join us to learn the Blend UI and see how far Blend can take your XAML projects. We will cover the controls and settings within Blend to give you a basic foundation to move forward from. Although many things will be touched upon in order to show off the gui controls, this talk is not a deep dive into XAML, building complex controls, or live data integration. It is a good foundation for those discussions to follow.";
     DeliveredOn = 5/8/2010 12:00:00 AM;
     GroupID = 1;
     LiveAuthors = seq [];
     LiveGroup = null;
     LiveTags = seq [];
     LiveVideos = seq [];
     PresentationID = 1;
     Title = "Expression Blend 4";}

I just retrieved one presentation with the following line:

  let onePresentation = Seq.head inetaDatabase.LivePresentations

This way, I can check the properties provided by that LivePresentation instance. The following lines show another example of using the ODataService type provider to retrieve the first live presentation that includes "Blend" in its abstract.

module OdataConnectivity = 
    open System
    open System.Data
    open Microsoft.FSharp.Data.TypeProviders

    [<Literal>]
    let InetaServiceAddress = "http://live.ineta.org/InetaLiveService.svc/"
    
    type InetaCatalog = ODataService<InetaServiceAddress>

    let inetaDatabase = InetaCatalog.GetDataContext()

    let GetFirstPresentationTitleByAbstractWord abstractWord = 
        query {
            for presentation in inetaDatabase.LivePresentations do
            where (presentation.Abstract.Contains(abstractWord))
            headOrDefault
        }
        |> (fun presentation -> 
                if presentation = null then
                    "No matches found"
                else
                    presentation.Title)

    let firstBlendPresentationTitle = GetFirstPresentationTitleByAbstractWord "Blend"

    Console.WriteLine(firstBlendPresentationTitle)

    let ReadAnyKey() = 
        Console.WriteLine("Press any key to continue")
        Console.ReadKey() |> ignore

    ReadAnyKey()

This is straightforward code. InetaCatalog is the type abbreviation (or alias) for the ODataService type provider. The GetDataContext static method gets a simplified data context for the OData service. inetaDatabase is of type InetaCatalog.ServiceTypes.SimpleDataContextTypes.INETALivePublic. Because the type provider already established the connection and generated the necessary types, when you enter "inetaDatabase," IntelliSense displays the available methods, such as GetDataContext and the ServiceTypes with all the types required for the service as nested types.

If you enter the following lines:

  let GetFirstPresentationTitleByAbstractWord abstractWord = 
   query {
   for presentation in inetaDatabase.

You will notice how IntelliSense displays all the initial collections exposed by the OData service (see Figure 8):

  • LiveAuthors
  • LiveGroups
  • LivePresentations
  • LiveTags
  • LiveVideos

[Click image to view at full size]
Figure 8: IntelliSense displaying the Credentials and DataContext properties, and the collections that you can use as the source in a query expression.

In the previous example, the code uses LivePresentations as the data source for a query expression. Once you start writing the lines that define the query expression, the type inference mechanism knows that presentation is of type InetaCatalog.ServiceTypes.LivePresentation. Thus, after you write "presentation," IntelliSense displays the different fields available for the entity.

If you execute the code, you will see the title for an old presentation related to Blend on the console:

Expression Blend 4 Press any key to continue


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video