Monday, November 23, 2009

Using an interface to reuse Linq queries

I just read a post about convention based Linq querying and thought I would followup with an alternative method for implementation.

One downside that I see with the implementation of building the expression tree is that the entity may not have an Id property. In this case I would definitely want to see a compile error rather than runtime.

So a simple solution may be to decorate the entities with a marker interface and the place the constraint on the extension method generic, such as

    public interface IEntity
    {}
    
    public partial class Post : IEntity
    {
        // Id property is declared in the Linq to Sql designer file
    }

    public static T GetById<T>(this IQueryable<T> query, int id) where T : class, IEntity
    {
        ...
    }

But why don't we take this a step further and remove a bit of the expression clumsiness? If we were to add an Id property to the interface, then the following would be possible.
    public interface IEntity
    {
        int Id { get; set; }
    }
    
    public partial class Post : IEntity
    {
        // Id property is declared in the Linq to Sql designer file
    }
    
    public static T GetById<T>(this IQueryable<T> queryable, int id) where T : class, IEntity
    {
        return queryable.SingleOrDefault(t => t.Id == id);
    }

This implementation won't compile if the query is on an object that doesn't have an Id. Thus making the interface self-documenting and enforced at compile time.

So as an exercise in understanding expressions this implementation is lacking, but the simplicity is certainly appealing to me.

kick it on DotNetKicks.com Shout it