Searching an array of strings is not terribly interesting
(although sometimes actually useful). More interesting would be the ability to
search and work against richer collections of our own making. The good news is
that LINQ makes this easy. For example, to better track trips I can create a
simple class called “Location” in my project below:
Listing 5
using System;
public class Location
{
// Fields
private string _country;
private int _distance;
private string _city;
// Properties
public string Country
{
get { return _country; }
set { _country = value; }
}
public int Distance
{
get { return _distance; }
set { _distance = value; }
}
public string City
{
get { return _city; }
set { _city = value; }
}
}
This exposes 3 public properties to track the County, City
name and Distance from Seattle. I can then create a Step2.aspx file with a
GridView control that defines 3 columns like so:
Listing 6
<%@ Page Language="C#" CodeFile="Step2.aspx.cs" Inherits="Step2" %>
<html>
<body>
<form id="form1" runat="server">
<h1>Cities and their Distances</h1>
<asp:GridView ID="GridView1" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:BoundField HeaderText="Country" DataField="Country" />
<asp:BoundField HeaderText="City" DataField="City" />
<asp:BoundField HeaderText="Distance from Seattle" DataField="Distance" />
</Columns>
</asp:GridView>
</form>
</body>
</html>
I can then populate a collection of Location objects and
databind it to the Grid in my code-behind like so:
Listing 7
using System;
using System.Collections.Generic;
using System.Web;
using System.Query;
public partial class Step2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
List<Location> cities = new List<Location>{
new Location
{ City="London", Distance=4789, Country="UK" },
new Location
{ City="Amsterdam", Distance=4869, Country="Netherlands" },
new Location
{ City="San Francisco", Distance=684, Country="USA" },
new Location
{ City="Las Vegas", Distance=872, Country="USA" },
new Location
{ City="Boston", Distance=2488, Country="USA" },
new Location
{ City="Raleigh", Distance=2363, Country="USA" },
new Location
{ City="Chicago", Distance=1733, Country="USA" },
new Location
{ City="Charleston", Distance=2421, Country="USA" },
new Location
{ City="Helsinki", Distance=4771, Country="Finland" },
new Location
{ City="Nice", Distance=5428, Country="France" },
new Location
{ City="Dublin", Distance=4527, Country="Ireland" }
};
GridView1.DataSource = from location in cities
where location.Distance > 1000
orderby location.Country, location.City
select location;
GridView1.DataBind();
}
}
The above code-behind shows off a few cool features. The
first is the new C# 3.0 support for creating class instances, and then using a
terser syntax for setting properties on them:
Listing 8
new Location { City="London", Distance=4789, Country="UK" }
This is very useful when instantiating and adding classes
within a collection like above (or within an anonymous type like we’ll see
later). Note that rather than use an array this time, I am using a Generics
based List collection of type “Location”. LINQ supports executing queries
against any IEnumerable<T> collection, so can be used against any
Generics or non-Generics based object collections you already have.
For my LINQ query I’m then returning a collection of all
cities that are more than 1000 miles away from Seattle. I’ve chosen to order the
result in alphabetical order – first by country and then by city name. The
result of this LINQ query is again dictated by the type of the “location”
variable – so in this case of type “Location”:
Listing 9
IEumerable<Location> result = from location in cities
where location.Distance > 1000
orderby location.Country, location.City
select location;
When I databind this result against the GridView I get a
result like so:
Figure 4
<img border=0 width=392 height=458src="/ArticleFiles/922/image004.jpg">