1
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!

Boy Pasmo
  • 8,021
  • 13
  • 42
  • 67
  • 1
    There is no need to use `await` in yout first method. It is creating a redundant state machine. You can take off the `async` from your method signature and simply `return Context.FindByAsync(id);` – Yuval Itzchakov May 18 '14 at 14:43

2 Answers2

1

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.

Agent Shark
  • 517
  • 2
  • 6
1

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

Bassam Alugili
  • 16,345
  • 7
  • 52
  • 70
  • 1
    What do you mean by `your method(caller) must be here also Async otherwise, you have to use task.` do you mean use the word `await`? – Boy Pasmo May 18 '14 at 14:53
  • 1
    hi this what I mean for example your method is not async and let say you can not put the async keyword on the method for any reason on this method and you want to call GetByIdAsync then read this:http://stackoverflow.com/questions/19010337/calling-an-async-method-from-a-synchronous-method – Bassam Alugili May 18 '14 at 15:15
  • One last question though, wouldn't be great if I'll use async all throughout the application? Whether it's small or big app? – Boy Pasmo May 18 '14 at 15:20
  • Async await pattern can be used for app with only one button or with a very big application the concept behind that JUST THE USER INTERFACE WILL NOT BLOCKED so if the button need 5 min to do the job the UI will still not FREZED and you can click other buttons one thing still important the run will be in the main thread so ASYNC keyword will not create a new thread for everything will be in main thread very nice and simple solution for freezing or hanging problem - I have also read a lot of nice questions in your list :-) will vote them – Bassam Alugili May 18 '14 at 15:29
  • 1
    Thanks! Think you can add what you've just said in your answer? It would be great for added reference :) – Boy Pasmo May 18 '14 at 15:36