Boy Pasmo
Boy Pasmo

Reputation: 8481

Task<TEntity> preferred way to do repository

public async Task<TEntity> GetByIdAsync(int id) {
  return await Context.FindByAsync(id);
}

and

public IQueryable<TEntity> GetById(Expression<Func<TEntity, int>> predicate) {
  return Context.Where(predicate).FirstOrDefault;
}

I'm new to repositories and looking for tutorials and now kinda know what it does but the Task struck me. Between the two which is more preferred? I know it's a stupid question but it would help me understand them better. Any help would be much appreciated. Thanks!

Upvotes: 1

Views: 3024

Answers (2)

Bassam Alugili
Bassam Alugili

Reputation: 17003

First to your question:

GetByIdAsync: is used to load the data asynchrone from the database, If you have a lot of data for example you have to load about 10000 entries from database then this method it will be the right choice(You can also use bulk operation).

GetById: synchrone load the data from the DB this method is good if your query take just a few milliseconds and does not be called a lot of times from the same thread.

How to use them:

var employee= await new EmployeeRepository.GetByIdAsync(1);---> your method(caller) must be here also Async otherwise, you have to use task.

var employee= new EmployeeRepository.GetById(1);

If your Repository class return IQueryable then you have to do ToList.First();

You need Entity framework 6 or later =>> support of Async., otherwise you have to do it by your self!

Example: Let say your business object:

public class Employee
{

    public int Id { get; set; }
    public string FullName { get; set; }
}

// Now using this we will have a simple context class.
public class HRContext : DbContext
{        

    public DbSet<DomainClasses.Employee> Employees { get; set; }
}

// After that, define the repository interface IEmployeeRepository.
public interface IEmployeeRepository : IDisposable
{
    IQueryable<Employee> All { get; }
    IQueryable<Employee> AllAsync { get; }
    IQueryable<Employee> AllIncluding(params Expression<Func<Employee, object>>[] includeProperties);

    Employee Find(int id);
    Employee FindAsync(int id);
    void InsertOrUpdate(Employee employee);
    void Delete(int id);
    void Save();
}

// Then the Repository class called EmployeeRepository. 
public class EmployeeRepository : IEmployeeRepository
{
    HRContext context = new HRContext();

    public IQueryable<Employee> All
    {
        get { return context.Employees; }
    }

        public IQueryable<Employee> AllIncluding(params Expression<Func<Employee, object>>[] includeProperties)
        {
        IQueryable<Employee> query = context.Employees;

        foreach (var includeProperty in includeProperties)
        {
               query = query.Include(includeProperty);
        }

        return query;

    }

    public Employee Find(int id)
    {
        return context.Employees.Find(id);
    }

    public void InsertOrUpdate(Employee employee)
    {
        if (employee.Id == default(int)) {

            // New entity
            context.Employees.Add(employee);

        } else {

            // Existing entity
            context.Entry(employee).State = EntityState.Modified;
        }
    }

    public void Delete(int id)
    {
        var employee = context.Employees.Find(id);
        context.Employees.Remove(employee);
    }

    public void Save()
    {
        context.SaveChanges();
    }

    public void Dispose() 
    {
        context.Dispose();
    }

}

I get the soruce code from : http://blogs.msdn.com/b/wriju/archive/2013/08/23/using-repository-pattern-in-entity-framework.aspx

For example for a generic repository:

public interface IGenericRepository<T> where T : class {

    IQueryable<T> GetAll();
    IQueryable<T> GetAllAsync();
    IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
    IQueryable<T> FindByAsync(Expression<Func<T, bool>> predicate);
    void Add(T entity);
    void Delete(T entity);
    void Edit(T entity);
    void Save();
}

Where T is the base entity for all your entities. here is the complete generic example: http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle

For better separation of concern you can also combine the repository pattern with unit of work as described by Martin Fowler book: http://martinfowler.com/eaaCatalog/unitOfWork.html

Upvotes: 1

Agent Shark
Agent Shark

Reputation: 525

Those two pieces of code do different things.

First piece finds a single entity.

var user = await new Repo<User>.GetByIdAsync(12);

Second piece executes the where clause and returns the first element or null. It is badly named because it does not actually force searching by Id.

var user = new Repo<User>.GetById(u => u.Username=="Bob");

The task is there to support .NET 4.5 await and async commands.

Upvotes: 1

Related Questions