Now that LinqToLfsWorld
has been out for a couple of days, I've got time to explain a bit more
about the features, using the demo website as an example.
The v0.8 Preview release contains the code library and the demo
website for you to have a look at the interface first-hand. I should
probably mention that for release 1.0 this will probably change; I'll
make the demo website a separate and optional download, and the library
in a separate download on its own. This blog post will use that demo
website as an example.
The Code
Here's the code from the code-behind file, which I'm going to be referring to throughout this post:

If you've ever used Linq To Sql, you would be familiar with the
methodology at work here. Essentially, to query LfsWorld you would do
the following:
- Create a new instance of the LfsWorldContext
- Write a LINQ query to retrieve results using one of LfsWorld's services (hosts, racer stats, world records, etc).
- Step through the returned data or bind to a data control.
- Dispose the instance of LfsWorldContext
Let me explain a few things about this, starting with the LfsWorldContext itself.
The context has a strongly-typed collection representing each of the
services exposed in v1.4 of the pubstat service. To make these queries,
it requires that you supply it your credentials which you use to access
LfsWorld (either your username and password, or your ident key if you
have one). You can do this in two ways - through the LfsWorldContext
constructor, or through the configuration file (see Configuration below).
The context has CachingEnabled set to true by default
- I've explicitly set it above just for clarity. Whenever you make a
request to LfsWorld, the response gets cached for later. This is done
for performance reasons and, given that LfsWorld access isn't free for
premium users, protected your wallet! The cache time can be configured
using the CacheTime property on the context - just set this to a Timespan value of your choice.
Another caching strategy at work here is to protect those users which do not
have premium access to the LfsWorld service. Any request made within
five seconds of another one will throw an exception, and no request is
made to LfsWorld. This is also persistant across different context
instances. This behaviour can of course be switched off if you do have
premium access to the service, by setting the context's PremiumPubstatAccess property to true, which will allow you to make requests as quickly as you like. This property is false by default.

The next part at work here deals with an event handler, which allows
you to detect when any request has been made through the context
instance. This allows you to retrieve information about the url which
was sent to LfsWorld, the response it got back, whether it was cached
or not and the size of the data which was returned.

This piece of code actually builds the query. Note that it does just build
the query and does not actually execute it. This is the nature of Linq
queries - the data isn't retrieved until the results are evaluated (by
using a for-each loop or converting to a list, for example). You should
also note that the queries here can be quite fickle. This is a
limitation of the current version of LinqToLfsWorld and will be
improved by the 1.0 release.
What I mean by that is it is a bit limiting as to what you could use
in that query. For example, if I was querying racer stats I would use a
query like the following:
var stats = from s in context.RacerStats
where s.RacerName == "elkdanger"
select s;
This would work fine, as would:
string name = "elkdanger"
var stats = from s in context.RacerStats
where s.RacerName == name
select s;
But something like the following wouldn't (imaging GetRacerName() is some method I have created):
var stats = from s in context.RacerStats
where s.RacerName == GetRacerName()
select s;
What you would find is the context would try to sent a url to
LfsWorld which queries for a racer's statistics, would would pass
through an empty racer name parameter, resulting in LfsWorld returning
you no data. In fact, you'll find that any method operation inside that query would produce a similar result.
Another thing you'll notice is that for the initial query, only the
parameters that LfsWorld accepts for a given action will affect the
query (for example, querying racer statistices only accepts a "racer"
parameter) . This by design, and the intention is that users of
LinqToLfsWorld will make their initial query using only the parameters
available to them, evaluate that query and then use plain Linq To
Objects to deal with any further filtering that they might need. This
is the most flexible way and will give the programmer ultimate control
over the resultset.
At this point in the example, we evaluate the query by converting it
to a list, and selecting only those hosts which are currently
populated. At this point in the example we have a plain old list of
host objects in memory, which we can treat just like any other object.
Configuration
One thing you can't see in the code above is the configuration.
LinqToLfsWorld allows you to use a custom configuration section to
specify the same settings for all of your LfsWorldContext instances
(you can override them of course), making it easier to use this library
from multiple places in the same project.
The configuration file for the demo website project look like this:

These settings will apply to any instance of the LfsWorldContext
that you create, but of course can be overridden by any instance also.
The only required attribute here is authenticationMode, which should be set to 'IdentKey' or 'UsernamePassword'. Hopefully it should then follow that if you set authenticationMode to 'IdentKey', you must also supply the idenyKey attribute. Likewise for UsernamePassword authentication mode; you must supply the pubstatUsername and pubstatPassword
attributes. For the next release an xml schema file will be available
which will give you intellisense on this configuration section, so you
don't have to remember these. For now you can refer to the example site.
The next post will more than likely be an update on how progress is
being made towards the release of v1.0, once I have improved the
expression parsing side of things. Enjoy LinqToLfsWorld so far!