Home Contact

X

Coder, not artist.

News

Current archive is at: http://cskardon.wordpress.com/ - I aim to move it all soon! All code on here is free, but as a consequence it's up to you to check it, ha! If you have any questions, feel free to email: cskardon -- @ -- xclave dot co dot uk I'm sure you can decrypt the address there!

Twitter












Archives

Post Categories

Image Galleries

Syndication:

Icon Editing

Finally nearing the release of the app I’ve been working on for a little while now, and we near the final polishing points – Icons etc and a problem with the VS2008 icon editor… The problem being that VS2008 seems to have settings of 4bit icons only…

To the rescue comes Paint.NET and the Icon/Cursor Plug-in (both FREE).. This allows you to edit icon files properly, save in 32bit up to 256x256 (which is probably gonna be big enough :))

It’s pretty simple to use – to the effect that I managed to create this awesome mouse pointer in less than 10 seconds (I know – surprising eh? looks like it would’ve taken hours!) spiffy pointer


StringFormat annoyances in VS2008

I’ve been using StringFormat in my xaml quite a bit recently, and whilst I’ve liked it, I’ve found that code which is valid tends to cause VS2008 to no longer be able to represent the designer (which some might say is a good thing)…

Basically, the following code:

<TextBlock Text="{Binding MyValue, StringFormat=The value is {0}}"/>

causes VS to basically say ‘no way’ and can no longer render the xaml. Pressing F5 shows the Window just fine… Soo… What can we do about it?

If we modify the ‘StringFormat’ section to read as such:

<TextBlock Text="{Binding MyValue, StringFormat='The value is {0}'}"/>

VS can represent it just fine… The difference? The single quote characters around the value of the StringFormat.

Both versions are valid xaml, just VS can’t represent the former.

Ahh well.


Windows 7 - Media Center Video Error

Right,

Just a quicky this one - I didn't see anything online about this when I was searching for the solution but - basically - I fired up Media Center and went to watch Live TV, and I got the following error message:

Video Error: Files needed to display video are not installed or not working correctly. Please restart Media Center and or restart the computer

Uh oh..
This was working last night...
All I'd done was remove myself from the homegroup on the machine...
Hmmmm

Reinstalling video codecs - no joy.
Reinstalling video drivers - no joy.

Bugger.
Quickly test the TV I wanted to record last night did infact record...

"Cannot find file"

eh???

Browse to the files in explorer - there they are.. though I notice I needed to elevate to Administrator to run it...

Hmmm

Close Media Center... restart - but run as administrator...

Recorded TV - ok
Live TV??? -- ok...

Weird..

WCF and LINQ to SQL (Part 4 – Updates)

If you’ve read parts 1, 2 and indeed 3 you’ll know we’ve covered the CRD of CRUD, today we will cover the ‘U’ – updates! Updates are more complex than the other scenario’s we’ve covered so far, but not unmanageable. Also – in fairness this is a very simple update, more complex updates will require more thought (duh!) but this should be a good starting point. Let’s get to it!

We’ll start on familiar ground – updating the interface, adding an ‘UpdateCar’ method:

 
[OperationContract]
void UpdateCar(Car car);

 

and then we’ll need to implement this in the service:

 
public void UpdateCar(Car car)
{
    _db.Cars.Attach(car, true);
    _db.SubmitChanges();
}

 

Now let’s test it to see how it works (remembering to update our service reference in the client!)

 

CarsServiceClient client = new CarsServiceClient();
Car car = client.GetCar(5);
car.Make = "Fiat";
client.UpdateCar(car);

 

Fire up the console… ouch! InvalidOperationException!

 

InvalidOp_Update1

Let’s try one of the other overloads of the ‘Attach’ method…

 

public void UpdateCar(Car car)
{
    _db.Cars.Attach(car, GetCar(car.ID));
    _db.SubmitChanges();
}

 

Run… fail.. bum. Different exception though, we got a ‘DuplicateKeyException’:

 

DupKey_Update

Gah! It appears we can’t attach the object back to the DataContext, so… what about attempting to copy the members?

 

public void UpdateCar(Car car)
{
    Car original = GetCar(car.ID);
    original.Make = car.Make;
    original.Model = car.Model;
    _db.SubmitChanges();
}

 

Yup, that works, but doesn’t copy the Owner / Previous Owners, to achieve those goals we’d need to do them property by property as well; for example, to do the owner:

 
public void UpdateCar(Car car)
{
    Car original = GetCar(car.ID);
    original.Make = car.Make;
    original.Model = car.Model;
 
    original.Owner.Surname = car.Owner.Surname;
    original.Owner.Title = car.Owner.Title;
 
    _db.SubmitChanges();
}

 

Messy. Now, this is due to our disconnected manner of working (which we can’t do anything about whilst using WCF), so it’s a coding hit and a pain, as if we add a new property to the car, we need to update our ‘update’ method to deal with it. I guess you could consider going down a reflection route and copying all the properties across. Though – that would still be a pain – checking for ‘EntitySet’ types etc. But that seems complicated.

To be honest, this is the most annoying aspect. I can’t see any way to connect an object that has been created on a client. Maybe someone else knows, hmph, well…  That about rounds up the WCF / LINQ CRUD series.. (well, to a point)…

Cheers

Me


WCF and LINQ to SQL (Part 3 (Deletes))

If you’ve read parts 1 and 2 you’ll know we’ve covered the CR of CRUD, today we will cover the ‘D’ – deletions. We’ll need to update our interface to actually provide this functionality:

[ServiceContract]
public interface ICarsService
{
    [OperationContract]
    Car GetCar(int id);
 
    [OperationContract]
    void SubmitCar(Car car);
 
    [OperationContract]
    void DeleteCar(int id);
}

I’ve decided to delete the car via the identifier we created initially, though there is nothing to stop us using a ‘Car’ instance.

Anyhews, so, let’s code this up:

public void DeleteCar(int id)
{
    var car = GetCar(id);
    if(car == null)
        throw new ArgumentException("Car unknown!");
 
    _db.Cars.DeleteOnSubmit(car);
    _db.SubmitChanges();
}

Right, to perform a deletion we need the car instance, so we can just get that from our current library code. So… let’s test this bad boy… Remember to ‘Update’ our service reference…

UpdateServiceReference

So, we’ll use the following code:

CarsServiceClient client = new CarsServiceClient();
var car6 = client.GetCar(6);
client.DeleteCar(car6.ID);

(of course this does rely on you having a car with an id of ‘6’ in your db)

Once you’ve got this working (i.e. you have a valid car id) you’ll hit this problem:

SqlException_FK Foreign key constraints!! How do we get around this?

Well, we need to delete the owner first (and whilst we’re at it, the ‘PreviousOwners'), so let’s update the code:

public void DeleteCar(int id)
{
    var car = GetCar(id);
    if(car == null)
        throw new ArgumentException("Car unknown!");
 
    _db.Owners.DeleteOnSubmit(car.Owner);
    foreach (var owner in car.PreviousOwners)
        _db.PreviousOwners.DeleteOnSubmit(owner);
 
    _db.Cars.DeleteOnSubmit(car);
    _db.SubmitChanges();
}

Now when we run the code, we succeed!

There is another way to do the deletion, and that’s to write a stored proc that does the deletion in the correct order, and then, in the CarsDataContext edit the ‘DeleteCar’ method to call the stored proc instead. But I’ll leave that to you :)

So… All that’s left is the Update part of CRUD… and hopefully I’ll get that done soon!

Cheers!


Happy Ada Lovelace Day 2009 – Michele Leroux Bustamante!

I few months ago I took a pledge to:

"I will publish a blog post on Tuesday 24th March about a woman in technology whom I admire but only if 1,000 other people will do the same."

to celebrate Ada Lovelace day.

That time has come!

mlbsepia Michele Leroux Bustamante – author of a book I deem as one of the best books I’ve bought to get me into SOA and learning WCF… Without it I wouldn’t have got half as far as I have! Now – aside from the selfish reason of the fact that she has helped me with the book – I admire her because of the clarity of the writing, and the ease with which she can (and does) explain a complicated topic like WCF.

I know it’s not a streaming blog post essay of epic proportions (mainly because quite frankly, I’m a crap writer!), but it is about a woman in technology that I do admire!

So – Cheers to you Ada, and to you Michele!


WCF and LINQ to SQL (Part 2 (Creates))

Right, in my last post I wrote about creating a DBML file and hooking it all up through WCF, however, we only got to ‘retrieving’ from the database via the service. So, let’s presume you want to upload…

We already had our contract:

[ServiceContract]
public interface ICarsService
{
    [OperationContract]
    Car GetCar(int id);
 
    [OperationContract]
    void SubmitCar(Car car);
}

Of which we’ve tested the ‘GetCar’ method, let’s get to implementing the ‘SubmitCar’ method.

We actually did implement some code in our class:

 

public void SubmitCar(Car car)
{
    _db.Cars.InsertOnSubmit(car);
    _db.SubmitChanges();
}
But, will this work?

Well, our first problem is actually testing it. The WCF Test Client (which we get from an F5 call) is not particularly easy to use to create more complex calls, such as creating a ‘Car’ instance to upload.

Soooo…. We’d best create ourselves a client app.

Let’s go to our Solution Explorer, and add a new console project: ‘Client_Console’. Now, to get a service reference to this bad boy… so… Right click on the ‘references’ folder on the Client_Console project and select… ‘Add Service Reference’ (easy eh?)… Now click on ‘Discover’ and this should get your service from the solution.

Browse to the actual interface you want (probably only one there in this case :)), and give it a good namespace name – I’ve gone for ‘CarsService’ (imaginative eh?).

AddServiceReference

Now we have that we can code against it, so opening up the ‘program.cs’ file helpfully created by VS for the ‘Client_Console’ app we can construct a new Car instance.

Car car = new Car
              {
                  ID = 5,
                  Make = "Ford",
                  Model = "Focus",
                  Owner = new Owner
                              {
                                  Surname = "Milly",
                                  Title = "Ms"
                              },
                  PreviousOwners = new[]
                                       {
                                           new PreviousOwner {
                                               Surname = "Qwerty", Title = "Miss", 
                                               WhenBought = DateTime.Now.AddDays(-50)},
                                           new PreviousOwner {
                                               Surname = "Vanilly", Title = "Mr", 
                                               WhenBought = DateTime.Now.AddDays(-100)}
                                       }
 
              };

 

Great!

Let’s Submit!!!

CarsServiceClient client = new CarsServiceClient();
client.SubmitCar(car);

Ahhh! NullReferenceException??? What the hey???

NullRef

In fairness it’s true, the ‘PreviousOwners’ property on the 'server’ is null… But why? Well, the cars object was created in the client,not the server, as a result the constructor for the server version was never called. If we look at the constructor for the ‘Cars’ class we’ll see the following line:

this._PreviousOwners = 
    new EntitySet<PreviousOwner>(
        new Action<PreviousOwner>(this.attach_PreviousOwners), 
        new Action<PreviousOwner>(this.detach_PreviousOwners)
    );

 

okey dokey, let’s change the declaration of the _PreviousOwners member:

 
private EntitySet<PreviousOwner> _PreviousOwners = 
    new EntitySet<PreviousOwner>(
        new Action<PreviousOwner>(this.attach_PreviousOwners), 
        new Action<PreviousOwner>(this.detach_PreviousOwners)
        );

 

Ah. We can’t do that as we’re attempting to use ‘non-static’ methods in a member declaration… hmmm, back to the Property itself perhaps…

What about adding a check for null into the property itself…

[DataMember]
[Association(Name="Car_PreviousOwner", Storage="_PreviousOwners", ThisKey="ID", OtherKey="CarId")]
public EntitySet<PreviousOwner> PreviousOwners
{
    get
    {
        return this._PreviousOwners;
    }
    set
    {
        if(_PreviousOwners == null)
            _PreviousOwners = 
                new EntitySet<PreviousOwner>(
                    new Action<PreviousOwner>(this.attach_PreviousOwners), 
                    new Action<PreviousOwner>(this.detach_PreviousOwners)
                    );
        this._PreviousOwners.Assign(value);
    }
}

Right, so firing F5 on our client now, and lo-and-behold there we are! It works! IT ACTUALLY WORKS!!!

If go to our WCF Test Client and ‘GetCar’ for ID 5, we should get back our car we just inserted….

 

TestClient_Car_Get5Huzzah!

So, we have Create and Retrieve working from our CRUD code. Obviously we’ll need to work out Updates and Deletes next, (a new post methinks!).

I will leave you with one note, concerning the use of the dbml file.

Obviously, it’s a great time saver, the code is generated for you (for better or worse) and the associations etc are all setup, but once you’ve added your WCF attributes to the classes you’re only one step away from an accident. A little tweak to the dbml will regenerate all your code. Yes – that does mean you lose all the WCF goodness you’ve put there.

So, the solution to this? Split the file, once you’re content with your dbml, basically go through the *.designer.cs file and create a separate file with the contents in, then exclude the dbml file from the project. You should find it will all still work, you just won’t have the design interface.

Other benefits to this approach are that you can add in methods etc to the classes without fear of losing them.

Anyways, I will be back with part 3, concerning deletes at some near future point (updates will be part 4).


EntitySet.Contains – uses Reference comparisons - Addendum

I realised whilst reviewing some code that you can also implement the IEquatable<T> interface as well just overriding the Equals (or indeed, in place of doing that).

So, back to our Simple class, we could actually write it as such:

internal class Simple : IEquatable<Simple>
{
    public int TheInt { get; set; }
    public string TheString { get; set; }
 
    public Simple(int theInt, string theString)
    {
        TheInt = theInt;
        TheString = theString;
    }
 
    public bool Equals(Simple other)
    {
        if(other == null)
            return false;
 
        return TheInt == other.TheInt && string.Equals(TheString, other.TheString);
    }
}
 

This will work perfectly in a collection situation (though again, not the EntitySet), but will fail with the extension method we wrote last time… How?

Well, let’s say we perform the same test as in the last post:

public static void Run()
{
    EntitySet<Simple> simpleEs = new EntitySet<Simple>
                             {
                                 new Simple(1, "1"),
                                 new Simple(2, "2")
                             };
 
    Simple s2 = new Simple(2, "2");
    
    Console.WriteLine("Contains ES? " + simpleEs.Contains(s2));
    Console.WriteLine("Contains ES? " + simpleEs.ContainsUsingEquals(s2));
}

We will get the output:

Contains ES? false
Contains ES? false

Which isn’t what we want. Clearly when in our extension method we call:

e.Equals(t)

We are only calling the normal Equals method. We could modify this to read:

((IEquatable<T>)e).Equals(t)

Which would work as long as it was IEquatable<T> (in which case we’d be better off forcing our extension method to only work on objects implementing that interface:

public static bool ContainsUsingEquals(this EntitySet<T> es, T t)
    where T : class, IEquatable<T>
{ /**/ }

But that seems a bit limiting, so instead I modified the extension to just cover both scenarios. It will attempt to use the IEquatable<T> implementation first, and it that’s not there, use the original equals:

 

public static bool ContainsUsingEquals<T>(this EntitySet<T> es, T t)
    where T : class
{
    if (t is IEquatable<T>)
    {
        foreach (var e in es)
            if (((IEquatable<T>)t).Equals(e))
                return true;
    }
    else
    {
        foreach (var e in es)
            if (t.Equals(e))
                return true;
    }
    return false;
}

Of course it might be more efficient to do the cast of the ‘t’ to IEquatable<T> earlier and use the casted version rather than casting it each time…

meh


EntitySet.Contains – uses Reference comparisons

A gotcha that got me :)

If you’re used to using List<T> collections, and in particular the way they compare, then you need to know that an EntitySet (from LINQ to SQL) does the comparison differently…

In my experience, if I’ve created a class, for example:

 

internal class Simple 
{ 
    public int TheInt { get; set; } 
    public string TheString { get; set; } 
 
    public Simple(int theInt, string theString) 
    { 
        TheInt = theInt; 
        TheString = theString; 
    } 
} 

 

And I then add some instances of this class to a List<Simple>, if I want a ‘Contains’ call on this list to return true I would have to override the ‘Equals’ method.

For example, doing the following:

 

static void Main(string[] args) 
{ 
    List<Simple> simpleList = new List<Simple> 
                                  { 
                                      new Simple(1, "1"), 
                                      new Simple(2, "2") 
                                  }; 
 
    Simple s2 = new Simple(2, "2"); 
 
    Console.WriteLine("Contains? " + simpleList.Contains(s2)); 
    Console.WriteLine("Fin."); 
    Console.ReadLine(); 
} 

 

Will write out:

Contains? false 

If I then modify the Simple class and add the following method to it:

public override bool Equals(object obj) 
{ 
    Simple other = obj as Simple; 
    if(other == null) 
        return false; 
 
    return TheInt == other.TheInt && TheString == other.TheString; 
} 

and then run the Contains code again, I will get:

Contains? true 

Which is what I expect.

But what if we use an EntitySet?

static void Main(string[] args) 
{ 
    EntitySet<Simple> simpleEs = new EntitySet<Simple> 
                                     { 
                                         new Simple(1, "1"), 
                                         new Simple(2, "2") 
                                     }; 
 
    List<Simple> simpleList = new List<Simple> 
                                  { 
                                      new Simple(1, "1"), 
                                      new Simple(2, "2") 
                                  }; 
 
    Simple s2 = new Simple(2, "2"); 
 
    Console.WriteLine("Contains? " + simpleList.Contains(s2)); 
    Console.WriteLine("Contains ES? " + simpleEs.Contains(s2)); 
    Console.WriteLine("Fin."); 
    Console.ReadLine(); 
} 

In this case we get:

Contains? true 
Contains ES? false 

Which is not what I expect… So.. I did what any other dev would do and fired up Reflector and opened up the ‘System.Data.Linq.dll’ (c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\), and navigated to the EntitySet, then the Contains, and following that onto ‘IndexOf’ and then into ‘entities.IndexOf’ to discover it’s doing a reference comparison:

 

public int IndexOf(T item) 
{ 
    for (int i = 0; i < this.count; i++) 
    { 
        if (this.items[i] == item) 
        { 
            return i; 
        } 
    } 
    return -1; 
} 

 

See the ‘this.items[i] == item’ comparison? That bad boy is a reference comparison, in other collections (such as the List<T>) the reference comparison is only used if the item being compared is null.

Now, in fairness, this makes sense from the perspective of LINQ to SQL, clearly, the reference is the actual one we pulled from the database, and we want it to act that way most of the time. But what if we don’t?

I’ve chosen the Extension method route:

 

internal static class EntitySetExtensions 
{ 
    public static bool ContainsUsingEquals<T>(this EntitySet<T> es, T t) 
        where T : class 
    { 
        foreach (var e in es) 
            if (e.Equals(t)) 
                return true; 
 
        return false; 
    } 
} 

 

This initially seems to maybe be inefficient, but I can see from the reflected code that the implementation of ‘IndexOf’ in the EntitySet itself is doing a for loop, so I’m not too worried. Anyhews, if we go back to our example and change the code so instead of ‘Contains’ it uses ‘ContainsUsingEquals’ instead:

Console.WriteLine("Contains ES? " + simpleEs.ContainsUsingEquals(s2)); 

We get:

Contains ES? true 

Which is what I wanted. Obviously, ‘Contains’ will still return false!

WCF and LINQ to SQL

Now, I may be doing this wrong, but at the moment, it works :)

I’m writing a service to communicate with a database, and provide a consistent front end for the applications that will be using it.

In the past that has meant writing tonnes of CRUD (Create Read Update Delete) code, usually via Stored Procs, which are then accessed by a ‘DbAccess’ helper class of some variety. Not to mention the added bonus of writing the classes to store the data as it comes out.

Fortunately the database I’m accessing is small, and so I though it to be a good candidate for messing around with LINQ to SQL, and right I was too! Onto teh meaty stuff….

Lets say I have a database with 3 tables:

3_Car_Tables

 

To insert into this via the medium of SQL we’re looking at something like:

insert into Car (ID, Make, Model) values (1, 'Volvo', 'V40')
insert into Owner (CarId, Title, Surname) (1, 'Mr', 'Skardon')
insert into PreviousOwners(CarId, WhenBought, Title, Surname) values (1, '2003-02-02', 'Ms', 'Taylor')
insert into PreviousOwners(CarId, WhenBought, Title, Surname) values (1, '2001-02-02', 'Miss', 'Polton')

Which inevitably ends up becoming wrapped up in stored procs, probably one to Add the car and owner, and another to add previous owners. Eurgh.

Anyways, we all know that stuff, how about we LINQ it up…

LINQ to SQL – Really basic edition

First, we want a new VS2008 window…

Got it?

Ace – Let us proceed…. Create a new Console App, I’m calling mine ‘LinqToCar’, but you can call it whatever you like :)

AddNewItem

Once we have that, we add a new item to the project, and select the ‘LINQ to SQL Classes’ type, naming it (again) as you like.

AddNewItem2

In our new ‘dbml’ window we have we’ll have an empty tableau, let’s get filling it… Open up the ‘Server Explorer’ window in Visual Studio (CTRL+ALT+S), and add a Data connection to the Car database. Open up the ‘Tables’ folder and select all the tables, dragging them into the Object Relational Designer pane. You should end up with something like this:

ORD_View

Now we can switch back to our Program.cs file and start querying the database…

But first! We need a datacontext… Luckily we’ve already got one: ‘CarsDataContext’. So, let’s simply enter the following code:

 

class Program
{
    static void Main(string[] args)
    {
        CarsDataContext db = new CarsDataContext();
        var allCars = from c in db.Cars
                      select c;
 
        allCars.WriteCars();
        
        Console.WriteLine("Press ENTER to exit.");
        Console.ReadLine();
    }
}
 
internal static class CarsExtensions
{
    internal static void WriteCars(this IEnumerable<Car> cars)
    {
        foreach (var car in cars)
            Console.WriteLine(car.ID + ", " + car.Make + ", " + car.Model + ", " + car.Owner.Surname);
 
    }
}

The ‘CarExtensions’ class just adds an Extension method to be able to print the contents of an IEnumerable<Car> collection to the console. The important code is the actual selection, first we create our DataContext:

CarsDataContext db = new CarsDataContext();

Then we perform the query:

var allCars = from c in db.Cars
                      select c;

This (as the cunningly named variable suggests) gets us all the cars (nb, we could have written this in lambda stylee by doing:

var allCars = db.Cars.Where(c => c);

Anyhews, this is starting to come across as an introduction to LINQ to SQL – which it’s not meant to be. Needless to say, we can perform pretty much any query we want to on this now, experiment with it!

But where does the WCF stuff come into it?

Well, we have all our classes created by the designer - ‘Car’, ‘Owner’ and ‘PreviousOwner’, what would be great would be if we could have access to these via a service and not have to create ‘mapping’ classes.

Soooo… how do we go about doing that?

 

Converting the ConsoleApp to a WCFService

To be honest, the easiest thing to do here is actually start a new ‘WCF Service Library’ project and add a dbml to it in the same way we did above. So, lets do that. (remember to add the LINQ to SQL file as above!!!)

Assuming you are now staring at an ‘IService1.cs’ file in your VS window, what we should do is go to the Solution Explorer and rename the ‘IService1.cs’ file to something better - ‘ICarsService’ seems a good start. Once we’ve done that, let’s clear out the ‘CompositeType’ and the methods defined for us in the ICarsService interface. So we should end up with a file with the following contents:

 

[ServiceContract]
public interface ICarsService
{
}

 

Let’s add two methods, one to get a car, one to submit a car…

 

[ServiceContract]
public interface ICarsService
{
    [OperationContract]
    Car GetCar(int id);
 
    [OperationContract]
    void SubmitCar(Car car);
}

Ok, so now we need to go to the Service1.cs file and rename it to something like ‘CarsService’ and then open it for editing… Same deal as before, delete all teh methods given to us and implement the ones defined in the ICarsService.

public class CarsService : ICarsService
{
    public Car GetCar(int id)
    {
        throw new System.NotImplementedException();
    }
 
    public void SubmitCar(Car car)
    {
        throw new System.NotImplementedException();
    }
}

Let’s add some simple LINQ code here…

public class CarsService : ICarsService
{
    private static readonly CarsDataContext _db = new CarsDataContext();
 
    public Car GetCar(int id)
    {
        return _db.Cars.Where(c => c.ID == id).Single();
    }
 
    public void SubmitCar(Car car)
    {
        _db.Cars.InsertOnSubmit(car);
        _db.SubmitChanges();
    }
}

 

Cool, so… let’s press F5 and load up the WCF Test Client and invoke that bad boy…

‘GetCar’ – passing ID 1 (as I know it’s there)…

Gah! WebException…

‘An error occurred while receiving the HTTP response to http://localhost:8731/Design_Time_Addresses/CarsLibrary/Service1/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down).’

Hmmm… Ah, wait a minute… Sure, we’re attempting to pass down a ‘Car’ object, but we’ve not defined it as a DataContract… Let’s get onto that!

 

We need to open the Cars.designer.cs file and modify the ‘Car’ class.

First, we need to add the ‘DataContract’ attribute to the class…

[DataContract]
[Table(Name="dbo.Car")]
public partial class Car : INotifyPropertyChanging, INotifyPropertyChanged {...}

 

Next, we need to modify the properties, so, let’s find the properties, (in our case ‘ID’, ‘Make’, ‘Model’, ‘PreviousOwners’ and ‘Owner’ and add the ‘DataMember’ attribute to them:

[DataMember]
[Column(Storage="_ID", DbType="Int NOT NULL", IsPrimaryKey=true)]
public int ID {...}

 

Ace, now we’re rocking, let’s try again…

Gah! No we’re not… same error… oh wait, ahh yes, some of our properties refer to other classes (Owner etc) so we’d best DataContract / DataMember those bad boys as well…

Oh noes! Still doesn’t work.. Let’s have a look at those classes a bit closer…

What we’ve blindly done (I admit, I made you do this so please forgive me :)) is add the [DataMember] attribute to all the properties. Now, for the ‘Car’ class that is fine, desired in fact.. But what about the other classes? Well, inside those we have properties which are classed as ‘Association’ properties, (look at the attributes). How do these work?

Well… Lets say we’ve done a query, and have a Car object..

Car car = _db.Cars.Where(c => c.ID == 1).Single();

If we now use intellisense we can start skipping through the class…

car.Owner

Get’s us the Owner of the car.. but wait! There’s more!!

car.Owner.Car

??? Eh? Well, that gets us the owner of the car’s car…. but wait!! There’s even more!!!!

car.Owner.Car.Owner.......

A never ending stream of accessibility…!!! This is great internally to the service, but causes an infinite loop when trying to send the data down, (which is why you’ll get a ‘timeout’ exception).. The solution? Remove the ‘DataMember’ attributes from the [Association] properties…

Done?

F5 and try once more…

Huzzah!

We have a winner!!!

So, we can now Get a LINQ to SQL object from the service to our client.

I think that’ll be enough for this post… :) The next post will cover the uploading of data to our service…