Flylib.com

Books Software

 
 
 

Chapter 7. Extending LINQ


Chapter 7. Extending LINQ

In closing, let's touch on the extensibility of LINQ, another of its elegant design characteristics. As you have seen, LINQ interoperates with a range of data sources, from object graphs to relational databases to XML documents. Let's look at a quick example of how we go about extending one of our own classes to natively support LINQ.

Our running demo has focused on doctors working at the fictitious University Hospital. You've seen many queries involving doctors , often using the Distinct operator to eliminate duplicates. For example, a query to yield the distinct doctors working in October 2006:

DataSets.SchedulingDocs ds = FillDataSet();

var oct2006 = (
                from doc in ds.Doctors
                join call in ds.Calls
                on doc.Initials equals call.Initials
                where call.DateOfCall >= new DateTime(2006, 10, 1) &&
                      call.DateOfCall <= new DateTime(2006, 10, 31)
                select doc
              )
              .Distinct();

Since we designed the data model, we know that a doctor's initials are unique. We can take advantage of this information to optimize the application of Distinct in the query above by providing our own implementation specific to our DataSet:

using DS = DataSets.SchedulingDocs;

public static class

DataSetsExtension

{

  public static IEnumerable<DS.DoctorsRow>

Distinct

(this
                                                    IEnumerable<DS.DoctorsRow> src)
  {
    // optimize by using a hashtable with doctors' initials:
    System.Collections.Hashtable ht = new System.Collections.Hashtable();

    foreach(var doc in src)  // for each doctor in the original sequence:
    {
       if (ht[doc.Initials] == null)  // first time, so remember and return:
       {
          ht.Add(doc.Initials, doc.Initials);
          yield return doc;
       }
       else  // we've yielded this doc already, so skip:
          continue;
    }
  }

}//class

For sequences of type DoctorsRow i.e., doctors in our DataSetthis implementation will be used in place of the standard LINQ implementation of Distinct . Thus, for any query of the form,

var query = from doc in ds.Doctors
            .
            .
            select doc;

the application of Distinct will invoke our optimized implementation. That's it!



Chapter 8. For Further Information

For all things LINQ, start at http://msdn.microsoft.com/data/ref/linq/. This short video with Anders Hejlsberg and Luca Bolognese provides a great overview of LINQ: http://channel9.msdn.com/showpost.aspx?postid=114680. Finally, keep an eye out for LINQ- related webcasts by yours truly, which will be announced at the O'Reilly site for this Short Cut (http://www.oreilly.com/catalog/language1) and on my blog (http://www.pluralsight.com/ blogs /drjoe/).



Chapter 9. Acknowledgements

I'd like to thank the LINQ team at Microsoft for their insightful review of this Short Cut. The result is a much improved document, which benefits us all.