6
votes

I am using generic repository pattern with methods:

    private ObjectQuery<T> ObjectQueryList()
    {
        var list = CamelTrapEntities.CreateQuery<T>(EntitySetName);
        return list;
    }

    public IQueryable<T> List()
    {
        return ObjectQueryList();
    }

Metod List() returns IQueryable<T>, becase IQueryable<T> is easy to mock. I also have extension method:

    public static IQueryable<T> Include<T>(this IQueryable<T> obj, string path)
    {
        if (obj is ObjectQuery<T>)
            (obj as ObjectQuery<T>).Include(path);

        return obj;
    }

This method is used outside of repository to get entity list with navigation properties already loaded, for example: List.Include("CreatedBy"). The problem is that it doesn't work. All includes are ignored. when I change List() method to

    public ObjectQuery<T> List()
    {
        return ObjectQueryList();
    }

everything works fine.

How should I implement repository pattern to be able to execute more complex queries?

3

3 Answers

6
votes

Reflector gave me an answer:

public ObjectQuery<T> Include(string path)
{
    EntityUtil.CheckStringArgument(path, "path");
    return new ObjectQuery<T>(base.QueryState.Include<T>((ObjectQuery<T>) this, path));
}

Include returns new ObjectQuery object and my Include function returned old object. Changing to

public static IQueryable<T> Include<T>(this IQueryable<T> obj, string path)
{
    if (obj is ObjectQuery<T>)
        return (obj as ObjectQuery<T>).Include(path);

    return obj;
}

solved the problem. Few hours lost and I hate Entity Framework more:)

It made me also realise that I should create another List function with Include parameter and not allow doing includes outside repository.

1
votes

Here is the most comprehensive Repository pattern implementation I've seen for EF. I can't say for sure if it will allow you to do Include(), but if I read the implementation right it should.

1
votes

With EntityFramework 4.1, DbExtensions (System.Data.Entity.DbExtensions) resolves this problem, and natively adds both .Include([string path]) and .Include([property expression]) for any IQueryable<T>.

Just be sure that the project using your repository references EntityFramework, and, as with any extension methods, specify using System.Data.Entity; in your class file to gain access to these extensions.