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