Book review: Essential LINQ

A few months ago I wanted to look into LINQ to SQL and grabbed a copy of Essential LINQ. The book is targeted at people who are coming from .NET 2.0 or people who are new to LINQ. It’s is very well written, almost like you’re following a class with clear examples showing you how you can leverage the platform to suit your needs.

Essential LINQ

The new language features of .NET 3.0 are covered which enable LINQ in the first place so if that’s new for you no need to buy another book. All LINQ operators are explained using LINQ to Objects followed by a very thorough discussion of LINQ to SQL. Mapping, stored procedures, modifying objects and how you can plug into the system with extension methods. After diving deep into LINQ to SQL there’s only a very small description of the Entity Framework or LINQ to Entities. Which is probably, in hindsight, the biggest issue you can have with this book since it’s now the de facto standard of data access promoted by Microsoft. The book finishes with another in depth discussion of LINQ to XML which was new to me and just like LINQ to SQL you’ll be an expert by the end of the chapters.

So to wrap it up, the book reads like you’re being thaught by a very good teacher. If you want to make sure you know your basic LINQ this is the one you need.

How to support Contains in Entity Framework 3.5

How can you retrieve the products that are contained in a list of id’s ?

var ids = new List<int>() { 1, 2, 3, 500 };
using (var context = new AdventureWorksEntities())
{
  var products = from product in context.Products
                           where ids.Contains(product.ProductID)
                           select product;
  WriteProducts(products);
}

The good news, this is supported in Entity Framework v4.0, but since I’m on 3.5 I needed to find another solution. Luckily using the info from my previous post I can write an expression for this:

var ids = new List<int>() { 1, 2, 3, 500 };
using (var context = new AdventureWorksEntities())
{
  Expression<Func<Product, bool>> idMatching = null; 
  foreach (var id in ids)
  {
    int productId = id;
    if(idMatching == null)
    {
      idMatching = x => x.ProductID == productId;
    }
    else
    {
      idMatching = idMatching.Or(x => x.ProductID == productId);
    }
  }
  var products = context.Products.Where(idMatching);
  WriteProducts(products);
}

Combining expressions to use with the Entity Framework

You often have to create a screen where the information is filtered on a given condition and the user can set some more options through checkboxes. For instance, display all products of a certain category and those results should be able to be filtered on their active status.

We could send one query to the database to retrieve the products and then filter them in memory, but let’s try to use the database for all of this since they’re good at this. You’ll bump into several issues when trying to solve this and like most problems in software development someone else most likely encountered the same issue and has already found a solution. In this case take a look at this, albeit old, article which illustrates the problem and gives a solution. It will enable you to write code like this:

public class ProductFinder
{
  public  ICollection<Product> FindProductsBySubCategory(int subCategoryId, bool makeFlagMarked)
  {
    using(var context = new AdventureWorksEntities())
    {
      Expression<Func<Product, bool>> whereClause = x => x.ProductSubcategory.ProductSubcategoryID == subCategoryId; 
      if(makeFlagMarked)
      {
        whereClause = whereClause.And(x => x.MakeFlag);
      }
      return context.Products.Where(whereClause).ToList();
    }
  }
}