FirstOrDefault to the rescue
I have been tinkering with LINQ for quite a bit now and I came across a trivial question about how does LINQ return an entity. I'm going to start off by sharing you a very simple example just to illustrate. To begin, I'll create a Contact table:
Very simple stuff, I start by creating a schema, create the table and start inserting 3 records to it. The next thing I'm going to do is create a solution using Visual Studio 2008.
I have renamed the default Class1.cs to ContactDirector.cs. I will then add a LINQ to SQL Class and call it Contact.dbml. VS in turn will create a class for me called ContactDataContext behind the scenes. This class inherits from System.Data.Linq.DataContext.
After VS has done its code generation, I'm presented with the LINQ designer. I will go ahead and drag my newly created Contact table to the designer.
Ok, we're halfway there. I will now start writing a few code to go back to our initial topic. At first, I'll start using the very basic way of getting a contact back.
I know, I know it's not so elegant at all. But let me generate some unit test from this and I'll show you that indeed this works. But before I do that, I have to override a couple of members of the Contact class. The Equals and the GetHashCode methods. I have to implement a custom logic to compare one contact to another for my testing.
Here's my unit test auto-generated by VS, I just added the value for the contactId and the expected variables. You guys should really test this, VS is smart enough to generate the test stubs for you.
I just run the test and I get the result back as Passed:
Ok, moving back to the next way of getting our contact back, I have come up with this approach:
This actually will work but there's one tiny problem with it, if there's actually no element returned, this will throw a InvalidOperationException as the sequence doesn't contain any elements. I can easy surround this call with a try-catch block but that wouldn't feel right.
Now comes FirstOrDefault to the rescue:
FirstOrDefault will return the contact I'm looking for or it will return null if it doesn't find any contact that matches. If I actually passed in a contactId that doesn't exist and I change my unit test to do something like:
This actually returned a Passed result. I'm sure there are other ways to implement this but I thought this might be worth sharing.
Remeber, always check for null!