Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusable Querying in Entity Framework WITHOUT Repository. How?

Let me say, I have come to the conclusion (after a lot of trial) that Repository & Unit of Work when using Entity Framework is just wrong, wrong, wrong and this says why quite well.

But I really hate on those embedded queries. Question is, where can I put them instead if I'm so against a repository, etc? (clean answers only please, examples much appreciated).

I just nuked two projects containing my repositories, unit of work and interfaces with hundreds of files because the payback was nowhere to be seen. I think lots of people, myself included, just jumped on the Repository bandwagon because that's what everybody else was doing but in retrospect, I think it's really a ride to nowhere.

/sigh

Richard

like image 235
Richard Avatar asked Aug 05 '11 01:08

Richard


People also ask

Is repository pattern needed with Entity Framework?

No, the repository/unit-of-work pattern (shortened to Rep/UoW) isn't useful with EF Core. EF Core already implements a Rep/UoW pattern, so layering another Rep/UoW pattern on top of EF Core isn't helpful.

Is DBcontext unit of work?

The Entity Framework DbContext class is based on the Unit of Work and Repository patterns and can be used directly from your code, such as from an ASP.NET Core MVC controller. The Unit of Work and Repository patterns result in the simplest code, as in the CRUD catalog microservice in eShopOnContainers.

Do we need unit of work with Entity Framework?

Not necessarily. EF already provides the unit of work pattern for you. The only reason to still have a unit of work is if you: want to include non-EF-datasources in an atomic data operation.


1 Answers

Where do you expect to put them? You have only few choices:

  1. Let them be where they are and use custom extension methods, query views, mapped database views or custom defining queries to define reusable parts
  2. Expose every single query as method on some separate class. The method mustn't expose IQueryable and mustn't accept Expression as parameter = whole query logic must be wrapped in the method. But this will make your class covering related methods much like repository (the only one which can be mocked or faked). This implementation is close to implementation used with stored procedures.
  3. You will do the same as in previous method but instead of placing queries in separate class you will put them as static methods to entity directly. This is much worse testable because static methods cannot be replaced by mocking (it requires more complex testing framework). This is part of active record pattern where each entity is responsible for its loading and saving to database.

Example of custom extension method:

public static IQueryable<TEntity> GetByName(this IQueryalbe<TEntity> query, string name) 
    where TEntity : IEntityWithName
{
    return query.Where(e => e.Name == name);
}

Example of custom class exposing methods:

public class QueryProvider
{
    public QueryProvider() {}

    public IEnumerable<TEntity> GetByName(IYourContext context, string name)
        where TEntity : IEntityWithName
    {
        return context.CreateObjectSet<TEntity>().Where(e => e.Name == name).ToList();
    }
}
like image 178
Ladislav Mrnka Avatar answered Oct 13 '22 10:10

Ladislav Mrnka