LINQ Basics (Part 2) – LINQ to SQL in .NET 4.0

Continuing my 2 part series on LINQ Basics, here I will attempt to discuss a few improvements in LINQ to SQL as part of the .NET 4.0 release scheduled soon. A key post on the 4.0 changes is by Damien Guard who works on LINQ at Microsoft along with other products. This will allow me to discuss some of the changes but also go into a bit more detail extending the “basics discussion” started in the previous post.

Note: In October 2008 there was a storm of discussion about the future of LINQ to SQL, in response to a focus shift from Microsoft for “Entity Framework”, the key reference post for this is again one by Damien G.

The upcoming 4.0 release doesn’t to cause damage to the capability of LINQ to SQL as people may have been worried about (i.e. disabling/deactivation in light of the discussions of Oct 2008). There are actually a reasonable amount of improvements, but as always there’s a great deal of potential improvements that there was not capacity/desire to implement for a technology set that is not a major focus. But LINQ to SQL is still capable enough to function well to be used for business systems.

First up there are some performance improvements in particular surrounding caching of lookups and query plans in it’s interaction with SQL Server. There are a few but not all desired improvements in the class designer subsystem, including support for some flaws with data-types, precisions, foreign key associations and general UI behaviour flaws.

There is a discussion on Damien’s post about 2 potential breaking changes due to bug fixes.

  1. A multiple foreign key association issue – which doesn’t seem to be a common occurrence (in any business systems I’ve been involved in).
  2. A call to .Skip() with a zero input: .Skip(0) is no longer treated as a special case.

A note on .Skip(), such a call is translated into subquery with the SQL NOT EXISTS clause. This comes in handy with the .Take() function to achieve a paging effect on your data set. There seems to be some discussion on potential performance issues using large data sets, but nothing conclusive came up in my searches, but this post by Magnus Paulsson was an interesting investigation.

As for the bug It does seem logical to have treated it as a special case and possibly help simplify code that might be passing a zero (or equivalent null set), but if it was an invalid case for .Skip() to be applied to with a value greater than zero it will fail forcing you to improve the query or its surrounding logic.

Just for the sake of an example here is .Skip() & .Take(). Both methods have an alternate use pattern too: SkipWhile() and TakeWhile(). The while variants take as input a predicate to perform the subquery instead of a count.

var sched = ( from p in db.Procedures  
             where p.Scheduled == DateTime.Today  
             select new {  
                      p.ProcedureType.ProcedureTypeName,  
                      p.Treatment.Patient.FullName  
                     };
                ).Skip(10).Take(10);

There are also improvements for the use of SQL Metal which is the command line code generation tool. As a side note to make use of SQL Metal to generate a DBML file for a SQL Server Database execute the command as such in a Visual Studio command prompt:

    sqlmetal /server:SomeServer /database:SomeDB /dbml:someDBmeta.dbml

ServiceModelEx

I have brought up ServiceModelEx several times already, and thought I’d dedicate a post that I can link back to other times when I mention ServiceModelEx.

ServiceModelEx is a set of WCF extensions primarily written by Juval Lowy from IDesign.net. This library of extensions is called ServiceModelEx it is available as a free download. The library is accompanied by an extensive collection of demo applications covering the use of WCF in conjunction with ServiceModelEx.

To quote the front page of the demo and utility section:
IDesign serviceware are a set of original techniques, tools, utilities and even breakthroughs developed by the IDesign architects. The utilities are largely productivity-enhancing tools, or they compensate for some oversight in the design of WCF.

IDesign WCF Tools Interface

IDesign WCF Tools Interface

At the time of writing the current version of the resources-cd demo count was 133, with some overlaps and but all demonstrating some specific concept or approach.

The WCF Run-Down

Windows Communication Foundation (WCF) is a framework for building service-oriented applications. Using WCF, you can send data as asynchronous messages from one service endpoint to another.

Great… Lets try it out…

So how do you go about getting something up and running? We have to start somewhere… so let’s start by covering some of the basic concepts.

Service Contract
The bulk of the work in setting up WCF is achieved by the most simplest of attribute placement on an interface (or class). Best practice is to apply it to an interface.

[ServiceContract]
public interface IMyServiceContract
{
    [OperationContract]
    string GetData(int value);
}

Bindings

Define the configuration of the way messages will be communicated, transported and encoded. The examples being Synchronous vs Asynchronous, HTTP vs TCP, compression vs interoperability. This list and set of comparisons is by no means exhaustive. But for the majority of cases of you’re likely to choose either NetTCP or MSMQ (queued) if both systems (client+server) are using WCF. Otherwise you have an ASMX based client and your choice really should be WSHttpBinding (otherwise you’re supporting a legacy system and you have no choice but to use BasicHttpBinding.

Endpoints

The address to which clients can connect to the service. The key things to note are the protocol type in this case net.tcp, the port (anything high up will do), the bindingConfiguration that allows you to further define the communication method, and the reference to the contract defined earlier. The service can and expose multiple endpoints, and they can each be of varying type and configuration.

<system.serviceModel>
  <services>
    <service name="MyService">
      <endpoint
        address="net.tcp://localhost:8001/MyService" 
        binding="netTcpBinding"
        bindingConfiguration="myNetTcpBinding"
        contract = "IMyServiceContract" />
    </service>
    <bindings>
      <netTcpBinding>
        <binding name="myNetTcpBinding" 
          transactionFlow="true" />
        </netTcpBinding>
    </bindings>
  </services>
</system.serviceModel>

Just a tip if you find yourself debugging calls from a client application and if you’re anything like me and like to edit code live while continuing to debug you will cop a lot of timeout exceptions. It’s therefore handy to setup extra bindings you can use them in development naming them something obviously not required for production like ‘DevExtendedTimeouts’ (hopefully so someone remembers to remove them before shipping) the length of the name itself makes them stand out. This way you have a few more minutes before you get hit with a timeout – alter length to your own taste. In a future post I will cover how this can also be achieved programmatically including the use of compiler directives.

<bindings>
   <netTcpBinding>
      <binding name="myNetTcpBinding_DevExtendedTimeouts" 
         transactionFlow="true"
         sendTimeout="00:05:00" />
   </netTcpBinding>
</bindings>

Client Application

Once the service contract has been imported a proxy responsible for managing the life-cycle and connection to the service is what the client application can invoke to make calls. The client end configuration needs to list all the endpoints exposed by the service that it intends to use. A key thing to note is the client calls via the proxy should always perform a close action, to free up resources on the service. This can simply be achieved via a using() statement, your service implementation should also implement IDisposable.

    using ( IMyServiceContract proxy = new MyClient() )
    {
        proxy.SomeMethod();
    }

Client configuration leads onto the topic of hosting the WCF service which will be the next post “Being a Good Host“.