Type safety - LINQ to DataSets Part 2

Published 05 February 07 08:45 AM | dpblogs 

 

 

Back in the first post of this LINQ to DataSet series, I spent some time talking about what LINQ to DataSet is, and how it can be used to supplement the existing query capabilities in terms of what kind of queries you can write. Today, I will talk about how LINQ provides more than just increased capabilities; it also helps you to write more robust code!

 

Let’s take one of the examples from the previous post.

 

var query = from dataRow in customerDataTable.AsEnumerable()

            where r.Field<string>("LastName") == "Smith"

            select r.Field<string>(“FirstName”);

 

What is that Field method in the expression shown above; and what is it doing?

 

One of the key features of LINQ is that it is type safe, so it becomes much easier to write queries that are type checked at compile time. It is much nicer to get an error when compiling than from a runtime exception at a client site!

 

Field<T> method

However, the DataSet is not typed by default. When you retrieve a value from a DataTable, the value is returned as an object. The Field<T> method returns the value of the column, returning it as the generic type parameter, thus enabling type checking.

 

That is not all the Field<T> method does! When the DataSet was first created, there was no concept of nullable value types in the CLR, so a new value type was defined: DBNull. This was used to represent null values for DataColumns that contain a value type, because you could not have have a null value type. The world has moved on, and we now have nullable types, and so it is now much more natural to write a query using null, as opposed to having to check for DBNull everywhere. The other feature offered by the Field<T> method is that it will convert a value type that has a value of DBNull.Value to a nullable type with a value of null.

 

var query = orderDataTable.AsEnumerable()

    .Where(dr => dr.Field<datetime>("OrderDate") == null)

    .Select(dr => dr.Field<int>("OrderID"));

 

As a nice bonus, you can use the Field<T> method in your non-LINQ code as well. If you do not have the option to use a typed DataSet, this a great way to reduce your typing, both in terms of errors and on the keyboard!

 

Typed DataSet

The Typed DataSet is another story. With this little gem, you already have fully typed access to your data, so you do not need to jump through hoops in order to use it in a LINQ to DataSet query.

 

EmployeesTable employees = new EmployeesTable();

var query = employees

    .Select(emp => new {

                       EmployeeID = emp.ID,

                       EmployeeName = emp.Name,

                       Employee = emp}

                       )

                       .OrderBy(e => e.EmployeeName);

 

As you can see, the lack of all the generic method calls certainly makes for more readable code! However, one thing to keep in mind is that the typed DataSet does not have the same logic for handling nulls as the Field<T> method. If you attempt to access a field that has a value of DBNull, you will get an exception from the property getter, which does not work very well with LINQ. There are ways to work around this problem, which I will explore later.

 

Coming soon…

 

In future LINQ to DataSet posts, I will talk more about how to handle nulls, and talk about some cool features of VB.NET that make the whole process easier.

 

Erick Thompson

Program Manager, ADO.NET

 

LINQ to DataSet Part 1

 

LINQ to DataSet Part 3

 

Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Eisenberg said on February 6, 2007 12:38 PM:

Why even bother with datasets?  I was hoping that MS was going to wise up and mark this functionality as Deprecated or Obsolete in the next version of ADO.NET.  (Isn't the Entity Framework supposed to replace DataSets?) Every scenario I have examined that uses datasets has had major issues and generally horrid software design.  They are the most embarassing and backwards part of .NET.

# Beth said on February 6, 2007 5:59 PM:

I'm really looking forward to your VB.NET sample.

# Erick Thompson said on February 9, 2007 9:45 AM:

Hi Eisenberg,

Thank you for taking the time to read our blog. The DataSet is actually a widely used component, and is quite good at what it was designed to do. While there may be some horrid software designs out there that use it, I think that could be said for a lot of other technologies as well. For an in-memory relational data cache, the DataSet is highly effective, and thus it makes perfect sense to enhance it with LINQ.

# John Papa [MVP C#] said on February 9, 2007 10:55 AM:

Here are a few good links to Orcas material (some old and some new). There is a lot of good and bad material

# Sam Gentile said on February 11, 2007 5:00 PM:

Winter has finally set in with single digit temps and minus degrees wind chills but still no snow. WPF/Avalon

# ADO.NET team blog said on February 15, 2007 3:51 PM:

Greetings fellow data junkies! My name is Erick Thompson, a PM at Microsoft who is working on driving

# daoud said on July 25, 2007 5:24 AM:

what is the vb.net equvelent for that code ?

# Jerin said on August 13, 2007 7:41 AM:

Will i be able to work with LINQ in my visual c# express edition 2005 version?

When i tried to include using System.Linq name space and tried to run the application it showed an error

Error 1 The type or namespace name 'Linq' does not exist in the namespace 'System' (are you missing an assembly reference?)

Can you please help me out??

# Nick said on September 21, 2007 8:16 PM:

I'm getting the same error:

The type or namespace name 'Linq' does not exist in the namespace 'System' (are you missing an assembly reference?)

and cant figure out what reference I need to make.  When I go to the website property pages / references and click "Add" I do not see a System.Linq to add as a reference.

Anyone have any ideas...?

# Nick said on September 21, 2007 8:24 PM:

I figured it out...  A reference to System.Core is needed in the progect...

# Paul said on January 15, 2008 5:39 AM:

Thanks Nick. I got to solve the problem through your post.

# Pramod said on July 21, 2008 1:54 AM:

Compare two large data tables A and B  using linq and get the records which exist  in dataTable A but does not exist in B

# Baraka said on October 25, 2008 10:28 AM:

I am new to the whole LINQ thing but I can see already that it is great technology. However, it is a shame that such great technology is handicapped by the fact it cannot create DataViews that are not limited by certain LINQ operators such as GROUP BY.

It has been a long time since it was introduced, by any chance has MS been able to make the LinqDataView free of its limitations? I certainly wish to use LINQ but its DataView limitations are putting me off.

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

Search

This Blog

Syndication

Page view tracker