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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With