Home > .net 3.5, c#, Visual Studio 2008 > LINQ – Projecting Properties into Lists

LINQ – Projecting Properties into Lists

May 28, 2008

I had a bit of code that iterated through the database, looked for distincts in a certain column, and then added those values into a List<int>.  That seemed a bit, well, overworked, for simply populating a drop down list. 

Why do I need a separate List object?  Why not simply compose it from my Select?

Original code:

public List<int> GetDistinctYears()

{

       var result =

              this.SelectAll()

                     .Where(i => i.SchoolYear == School.CurrentSchoolYear)

                      .Distinct();

 

       var years = new List<int>();

 

       foreach (var v in result)

       {

              years.Add(v.SchoolYear);

       }

 

       return years;

}

I don’t like that.  Additional loops just slows down the code.

The problem is in the LINQ statement and getting it right.

FAIL: Creating an anonymous type will fail because the compiler cannot convert it into a List<int>.

.Select(x => new { SchoolYear = x.SchoolYear } )

FAIL: You also can’t specify the type explicitly on creation because it tries to create an IEnumerable.

.Select(x => new int { x.SchoolYear } )

PASS: You can, however, specify exactly what you’re intending—an array—and using SelectMany instead of Select.

.SelectMany(x => new int[] { x.SchoolYear } )

PASS: You can also project the property itself (without newing it up), it’ll automatically be wrapped up into an IQueryable<T>.

.Select(x => x.SchoolYear)

Now, our new code looks a bit cleaner and should be faster without those excessive foreach loops.  This also converts our IQueryable<T> to a List<T>, or List<int> in this case.

Updated code:

return this.SelectAll()

       .Where(i => i.SchoolYear == School.CurrentSchoolYear)

        .Select(x => x.SchoolYear)

        .Distinct()

        .ToList();

NOTE: “Order of Operations” is extremely important when using Distinct—remember to complete all of your selecting BEFORE distincting. 

WHERE > SELECT > DISTINCT/GROUP > ORDER > CASTS.🙂

Tags:
%d bloggers like this: