Reusable Querying in Entity Framework WITHOUT Repository. How?

亡梦爱人 提交于 2019-12-05 05:13:10

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();
    }
}

Build Reusable, Testable Queries Part 1

This is a blog post I wrote about building reusable queries. Using Extension Methods allows you to build composable queries.

using a pattern like the specification pattern can help you build queries that can be reused or saved (serialized). Further more if you have a double entry system you can execute the same query instance over two different databases.

the following example does not use EF but replace the IEnumerable by an EF context and you get what ou are looking for. parameters are passed in through the constructor.

public class PartialMatchQuery : IModelQuery<string, IEnumerable<string>>
{
    private readonly string partial;

    public PartialMatchQuery(string partialString)
    {
        partial = partialString;
    }

    public IEnumerable<string> Execute(IEnumerable<string> model)
    {
        return model.Where(s => s.ToLower().Contains(partial));
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!