Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Repository Pattern why not return Iqueryable?

There are several good blogs about how to implement the repository pattern together with the unit-of-work pattern using generic classes.

Implementing a Data Access Layer with Entity Framework 6.1

Implementing the Repository and Unit of Work Patterns

The Idea is, to define a generic interface IRepository and a class Repository that hides how the data is actually accessed. It can be accessed using Entity Framework DbContext, or maybe the repository is an in memory collection for unit testing.

public interface public interface IRepository<T> where T : class
{
    T GetById(int Id);
    void DeleteById(int Id);

    void Add(T entity);
    void Update(T entity);

    etc.
}

Quite often I see that several Query functions are added that are similar to Queryable and/or Enumerable functions.

For instance in Implementing a data access layer I see:

/// Returns an IEnumerable based on the query, order clause and the properties included
/// <param name="query">Link query for filtering.</param>
/// <param name="orderBy">Link query for sorting.</param>
/// <param name="includeProperties">Navigation properties seperated by comma for eager loading.</param>
/// <returns>IEnumerable containing the resulting entity set.</returns>
IEnumerable<T> GetByQuery(Expression<Func<T, bool>> query = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "");

/// <summary>
/// Returns the first matching entity based on the query.
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
T GetFirst(Expression<Func<T, bool>> predicate);

If the interface had a function IQueryable GetQuery(), then I wouldn't have to make functions like GetFirst() and GetByQuery().

Question: Why is this not recommended? Can people change the data in an undesirable way?

like image 435
Harald Coppoolse Avatar asked Nov 17 '15 11:11

Harald Coppoolse


People also ask

Should repositories return IQueryable?

If they add a where clause to a deferred IQueryable , you only have to send that data over the wire, not the entire result set. If you are using repository pattern - no, you should not return IQueryable.

Should I use IQueryable?

IQueryable is best to query data from out-memory (like remote database, service) collections. While query data from a database, IQueryable execute the select query on the server side with all filters. IQueryable is suitable for LINQ to SQL queries. IQueryable supports deferred execution.

What is IQueryable return?

IQueryable<T> Return Type. The IQueryable<T> interface allows you to convert C# expressions into T-SQL queries for execution on the database side directly.

Is IQueryable in-memory?

The main difference between IEnumerable and IQueryable in C# is that IQueryable queries out-of-memory data stores, while IEnumerable queries in-memory data. Moreover, IQueryable is part of . NET's System.


1 Answers

This isn't recommended because it would invalidates the repository pattern. The purpose of this pattern is to keep your DAL implementation separate from your other projects by means of abstraction.

In essence returning an IQueryable would return the TSQL statement and NOT the results meaning any projects that reference your DAL would require additional references to EF to be able to perform the execution of the query. This 'data leak' would make your projects more tightly-knit and thus would contradict the separation of concern principle.

You can read more about the repository pattern and its benefits here: http://www.codeproject.com/Articles/526874/Repositorypluspattern-cplusdoneplusright

like image 171
Lee Avatar answered Oct 23 '22 11:10

Lee