Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I\'ve just had to switch out an ORM and it was a relatively daunting task, becau

ID: 642131 • Letter: I

Question

I've just had to switch out an ORM and it was a relatively daunting task, because the query logic was leaking everywhere. If i'd ever had to develop a new application, my personal preference would be to encapsulate all query logic (using an ORM) to futureproof it for change. Repository pattern is quite troublesome to code and maintain so i was wondering if there are any other patterns to solve the problem ?

I can foresee posts about not adding extra complexity before it's actually needed, being agile etc. but i'm only interested about the existing patterns solving a similar problem in a simpler way.

My first thought was to have a generic type repository, to which i add methods as needed to specific type repository classes via extension methods, but unit testing static methods is awfully painful. IE:

public static class PersonExtensions
{
    public static IEnumerable<Person> GetRetiredPeople(this IRepository<Person> personRep)
    {
        // logic
    }
}

Explanation / Answer

First of all: A generic repository should be considered to be a base class and not complete implementations. It should help you to get the common CRUD methods in place. But you still have to implement the query methods:

public class UserRepository : EntityFrameworkRepository<User>, IUserRepository
{
public UserRepository(DbContext context){}

public ICollection<Person> FindRetired()
{
return context.Persons.Where(p => p.Status == "Retired").ToList();
}
}
Second:

Do not return IQueryable. It's a leaky abstraction. Try to implement that interface yourself or use it without knowledge about the underlying db provider. For instance, every db provider has it's own API for eagerly load entities. That's why it's a leaky abstraction.

Alternative

As an alternative you can use queries (for instance as defined by the Command/Query separation pattern). CQS is described in wikipedia.

You basically create query classes which you invoke:

public class GetMyMessages
{
public GetMyMessages(IDbConnection connection)
{
}


public Message[] Execute(DateTime minDate)
{
//query
}
}
the great thing with queries is that you can use different data access methods for different queries without cluttering the code. you can for instance use a web service in one, nhibernate in another and ADO.NET in a third.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote