One of the exciting things in .Net 3.5 is LINQ. Being a device developer though can I use LINQ. You can use LINQ in Compact Framework 3.5 although not all features are available. Noticeably missing is LINQ for SQL. However that is not a big deal you get standard operators and being able to query objects and XML.
One thing to be really clear is that LINQ is mostly syntactic sugar. By that I mean it is just like a "using" clause. "Using" clause just cuts down on the typing you have to do so rather than System.String you can just put String. The compiler when it gets to the class name tries to find String. If it does not find it it appends the "using" clauses until it finds the class. For the most part this process is transparent until you have classes with the same name but in different namespaces. If the compiler can not figure out what class it complains and makes you mean further qualify the class name.
With LINQ it allows you to write SQL like syntax. The compiler then takes that SQL like statement and turns it into regular code that you as the programmer could have written. This is important to keep in mind.
So how does LINQ work for the Compact Framework? First, you need to make sure that System.Core is referenced. And second that you add
using System.Linq;
To the list of namespaces being used. If you do not do this you may see errors for example
Could not find an implementation of the query pattern for source type 'System.Collections.Generic.List<TestCFLinq.Customer>'. 'Where' not found. Are you missing a reference to 'System.Core.dll' or a using directive for 'System.Linq'? C:\Users\rsatter\Documents\Visual Studio 2008\Projects\TestCFLinq\TestCFLinq\FormLINQ.cs 45 42 TestCFLinq
You will definitely see this when converting from an older version of the Compact Framework to 3.5.
Listing 1
public class Customer
{
private int _customerId;
private string _customerName;
private string _streetAddress;
private string _city;
private string _stateProvince;
private string _postalCode;
private string _contactName;
private string _contactPhone;
private int _routeId;
public Customer() { }
public Customer(int customerId, string customerName, string streetAddress,
string city, string stateProvince, string postalCode,
string contactName, string contactPhone, int routeId)
{
this._customerId = customerId;
this._customerName = customerName;
this._streetAddress = streetAddress;
this._city = city;
this._stateProvince = stateProvince;
this._postalCode = postalCode;
this._contactName = contactName;
this._contactPhone = contactPhone;
this._routeId = routeId;
}
public string ContactPhone...
public string ContactName...
public string PostalCode...
public string StateProvince...
public string City...
public string StreetAddress...
public int RouteId...
public int CustomerId...
public string CustomerName...
If you have every dealt with object collections it is not easy to do complex queries against the collection. Using LINQ allows for doing SQL like queries against collections. Assume you have a class called Customer. With generics it is easy to create a typed collection of Customer via List<Customer> for example. To find one or more Customer objects in older versions of CF you would do something like in Listing 2.
Listing 2
List<Customer> query = new List<Customer>();
foreach(Customer currentCustomer in customers)
{
if (currentCustomer.CustomerId == 1)
{
query.Add(currentCustomer);
}
}
With LINQ it becomes very easy to make an easier statement that does the same thing. In Listing 3 the code in Listsing 2 has become a single line of code.
Listing 3
var query = from currentCustomer in customers where currentCustomer.CustomerId == 1 select currentCustomer;
So what is going on with this. First query will be a generic row. So if you want to know the count you would say query.Count<Customer>().
Second the contents of query are created using three main parts. The first is the "from" clause. The "from" clause tells the compiler where to draw objects from in this case I specified that it should loop through customers. In addition I tell the compiler I want a variable currentCustomer that gives you access to each customer. The next part is the "where" clause. Here I tell the compiler that I want it to select out customers that have a CustomerId of 1. The last part is the "select" clause. This allows you to tell the compiler what to do in this case add currentCustomer to the query result set.
Both accomplish the same thing. However, Listing 3 is much easier to understand not only what is going to happen but the intent of the programmer. And when you have very complex logic it becomes a no brainer which code I rather write and read.
Comments