Entity Framework and T4: Generate Query Objects on the fly, part 1

Generate Query Objects on the fly for your Entity Framework entities using T4 templates. Don’t worry about LINQ, let the objects do all the work for you.

Table of contents

  • Configuration
  • References
  • Downloads
  • I’ve read some stuff about T4 templates in the last 2-3 years, but only recently I decided to give it a try. My first attempt was to generate Query Objects for Entity Framework, that’s what I’ll talk about in this article – what’s their purpose and how to use them.

    In part 2 I’ll create a demo ASP.NET MVC application that uses query objects created with this template. I already have another T4 template that creates javascript objects for my entities, and I’m developing a custom ASP.NET view template for those objects.

    Many thanks to Colin Meek [4], his work has really helpful.

    What is a Query Object?

    A Query Object is an object that represents a database query [1]:

    A Query Object is an interpreter [Gang of Four], that is, a structure of objects that can form itself into a SQL query. You can create this query by referring to classes and fields rather than tables and columns. In this way those who write the queries can do so independently of the database schema and changes to the schema can be localized in a single place.

    Assuming that you have a repository like this (I’m using this implementation):

    public IQueryable All<T>(Expression<Func<bool, T>> expression) where T : class
    

    Instead of:

    var albuns = from x in repository.All<Album>()
                     where x.Artist.Name == "Metallica"
                     && x.Genre.Name.Contains("Metal")
                     && x.Price >= 5 && x.Price
                     select x;
    

    You can do this way:

    var search = new AlbumSearch();
    search.PriceFrom = 5;
    search.PriceTo = 10;
    search.Artist = new ArtistSearch(){ Name = "Metallica" };
    search.Genre = new GenreSearch(){ NameContains = "Metal" };
    
    var albuns = from x in repository.All<Album>(search.GetExpression())
                      select x;
    

    Continue reading