Chapter 2. A Quick Introduction to LINQ


Anders Hejlsberg, the chief architect of the C# programming language, summarizes LINQ quite nicely:

"It's about turning query set operations and transforms into first-class concepts of the language" (http://channel9.msdn.com/showpost.aspx?postid=114680)

Let's look at an example. Imagine we are writing a scheduling application for a hospital, where every night a doctor must be on call to handle emergencies. The main objects we are interacting with are of type Doctor, stored in a Doctors collection that inherits from List<Doctor>:

 Doctors doctors = new Doctors(); 

Suppose we need a list of all the doctors living within the Chicago city limits. The obvious approach involves a simple iteration across the collection:

 List<Doctor> inchicago = new List<Doctor>(); foreach (Doctor d in doctors)   if (d.City == "Chicago")     inchicago.Add(d); 

In LINQ, this search reduces to the following query, with the IDE providing keyword highlighting, IntelliSense, and compile-time type checking:

 var inchicago = from d in doctors where d.City == "Chicago" select d; 

Need a list sorted by last name? How about:

 var byname = from d in doctors              where d.City == "Chicago"              orderby d.FamilyLastName              select d; 

Also need a list sorted by pager number? In LINQ:

 var bypager = from d in doctors               where d.City == "Chicago"               orderby d.PagerNumber               select d; 

Finally, suppose we need a count of how many doctors live in each city (not just Chicago, but every city for which at least one doctor lives). With LINQ, we can compute this result by grouping the doctors by city, much like we would in SQL:

 var bycity = from d in doctors              group d by d.City into g              orderby g.Key              select new { City = g.Key, Count = g.Count() }; 

These types of queries begin to reveal the real power of LINQ. The results are easily harvested by iterating across the query, for example:

 foreach (var result in bycity)   System.Console.WriteLine("{0}: {1}", result.City, result.Count); 

This yields the following output for our set of doctors:

 Chicago: 5 Elmhurst: 1 Evanston: 3 Oak Park: 2 Wilmette: 1 

LINQ does not limit us to a read-only data access strategy. CRUD-like (create, read, update, and delete) operations are easily performed using the traditional object-oriented approach. For example, have the Larsens moved to the suburbs? If so, search for the appropriate Doctor objects and update the City:

 var larsens = from d in doctors where d.FamilyLastName == "Larsen" select d; foreach (var d in larsens)   d.City = "Suburb"; 

Need to create a doctor? Add an instance of the Doctor class to the doctors collection. Need to delete a doctor? Query to find the corresponding Doctor object, and remove from the collection. In short, while the LINQ API does not provide direct support for CRUD, these operations are easily accomplished.

NOTE

Here are the definitions of the Doctors and Doctor classes we'll be using throughout this Short Cut.

 public class Doctors : List<Doctor>  {     public Doctors()  // constructor (fills list with Doctors):     {        this.Add( new Doctor("mbl", "Marybeth", "Larsen", 52248,                             "mlarsen@uhospital.edu", "1305 S. Michigan", "Chicago",                             new DateTime(1998, 12, 1)) );        this.Add( new Doctor("jl", "Joe", "Larsen", 52249,                             "jlarsen@uhospital.edu", "1305 S. Michigan", "Chicago",                             new DateTime(1999, 11, 1)) );        this.Add( new Doctor("ch", "Carl", "Harding", 53113,                             "charding@uhospital.edu", "2103 Oak St", "Evanston",                             new DateTime(2000, 10, 1)) );        .        .        .     }  }  // continued   public class Doctor : IComparable<Doctor> // NOTE: IComparable NOT required by LINQ.  {         private string   m_Initials, m_GivenFirstName, m_FamilyLastName;         private int      m_PagerNumber;         private string   m_EmailAddress, m_StreetAddress, m_City;         private DateTime m_StartDate;         public string Initials         { get { return m_Initials;       } set { m_Initials = value; }       }         public string GivenFirstName         { get { return m_GivenFirstName; } set { m_GivenFirstName = value; } }         public string FamilyLastName         { get { return m_FamilyLastName; } set { m_FamilyLastName = value; } }         public int PagerNumber         { get { return m_PagerNumber;    } set { m_PagerNumber = value; }    }         public string EmailAddress         { get { return m_EmailAddress;   } set { m_EmailAddress = value; }   }         public string StreetAddress         { get { return m_StreetAddress;  } set { m_StreetAddress = value; }  }         public string City         { get { return m_City;           } set { m_City = value; }           }         public DateTime StartDate         { get { return m_StartDate;      } set { m_StartDate = value; }      }         public Doctor(string initials, string givenFirstName, string familyLastName,                int pagerNumber, string emailAddress, string streetAddress, string city,                DateTime startDate)         {                this.m_Initials       = initials;                this.m_GivenFirstName = givenFirstName;                this.m_FamilyLastName = familyLastName;                this.m_PagerNumber    = pagerNumber;                this.m_EmailAddress   = emailAddress;                this.m_StreetAddress  = streetAddress;                this.m_City           = city;                this.m_StartDate      = startDate;         }         public override bool Equals(object obj)  // NOTE: Equals NOT required by LINQ.         {                if (obj == null || this.GetType().Equals(obj.GetType()) == false)                  return false;                Doctor other = (Doctor) obj;                return this.m_Initials.Equals(other.m_Initials);         }         public override int GetHashCode()  // NOTE: GetHashCode NOT required by LINQ.         { return this.m_Initials.GetHashCode(); }         public int CompareTo(Doctor other)         { return this.m_Initials.CompareTo(other.m_Initials); }  } 



LINQ[c] The Future of Data Access in C# 3. 0
LINQ[c] The Future of Data Access in C# 3. 0
ISBN: N/A
EAN: N/A
Year: 2006
Pages: 25

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net