IQueryable Read Model Extension Methods

The normalized data model of the database is often not suitable for reading and displaying data. A separate read model used to represent all the data needed to display a page improves performance.

Defining the read model is only half the work though, to make it really usable the read model should accept queries in the same way as the write model (the DB Entities) does. In .NET/C# that means that the read model should implement IQueryable<T> to enable it to be queried with LINQ. By building the read model on top of the write model it becomes a breeze.

from c in ctx.Cars.SelectCarReadModel()
where c.Car.CarId == id
select c

A call to an extension method is all that’s needed – the query above produces a CarReadModel result, containing the additional data needed for displaying that’s not directly part of the Car entity.

Don’t use Linq’s Join. Navigate!

One of the greatest benefits of LINQ to SQL and LINQ to Entities is navigation properties that allows queries across several tables, without the need to use explicit joins. Unfortunately LINQ queries are often written as a direct translation of a SQL query, without taking advantage of the richer features offered by LINQ to SQL and LINQ to Entities.

It is not uncommon to see code doing a join manually.

from p in ctx.Persons
join c in ctx.Cities
on p.BornIn equals c.CityID
select new
{
    p.FirstName,
    c.Name
};

I think that using navigation properties makes the code much easier to read.

from p in ctx.Persons
select new
{
    p.FirstName,
    p.BornInCity.Name
};

Code Generation – Blessing or Curse?

There are lot of code generation tools available. Microsoft Visual Studio has had code generation possibilities since I started using it in the mid 90-ties. Code generation can be a blessing for getting something up and running quickly, but also a curse when maintaining code.

Whenever a code generation tool is considered, there are two very important aspects that need to be considered:

  • Is there support for regeneration when the code needs to be updated?
  • Are there possibilities to make adaptions without loosing them on regeneration?

Unfortunately a lot of the tools fail on at least one of these points. The blessing that helped creating something working quickly becomes a curse during further development and maintenance.

Using Transactions for Unit Tests

Unit tests should preferably be independent of external services, systems and files. The standard way to achieve this is to create mocks. A mock is an object that can be used in place of the real resource and act in a predictable way to ensure the tests always give the same result. I think that this is a perfectly valid approach for any external services that the system is integrated with. The problem for business applications is the database. Mocking the database by providing a mock implementation of the database access layer is a huge task. It is too huge to be worth the effort. Another approach that I often use is to use a database in the tests, but keep it unchanged through transactions.

Always Check Generated SQL

In my last post I advocated for using LINQ to SQL for data access. Today I am going to show an example of how the greater power of LINQ compared to SQL sometimes results in terrible performance when LINQ to SQL does it best to work around the limitations of SQL.

var q = from car in Cars
        where car.MadeIn == "Sweden"
        group car by car.Brand into brands
        select brands;

The question looks quite simple and straight forward, but has a hidden performance problem; it will send an extra SQL query to the server for each group.

Software Development is a Job – Coding is a Passion

I'm Anders Abel, an independent systems architect and developer in Stockholm, Sweden.

profile for Anders Abel at Stack Overflow, Q&A for professional and enthusiast programmers

Code for most posts is available on my GitHub account.

Popular Posts

Archives

Series

Powered by WordPress with the Passion for Coding theme.