public async Task<TEntity> GetByIdAsync(int id) {
return await Context.FindByAsync(id);
}
а также
public IQueryable<TEntity> GetById(Expression<Func<TEntity, int>> predicate) {
return Context.Where(predicate).FirstOrDefault;
}
Я новичок в репозиториях и искал учебники, и теперь я знаю, что он делает, но Task
поразила меня. Между этими двумя более предпочтительными? Я знаю, что это глупый вопрос, но это поможет мне лучше понять их. Любая помощь приветствуется. Благодарю!
Сначала на ваш вопрос:
GetByIdAsync: используется для загрузки данных asynchrone из базы данных. Если у вас много данных, например, вам нужно загрузить около 10000 записей из базы данных, то этот метод будет правильным выбором (вы также можете использовать массовую операцию).
GetById: synchrone загружает данные из БД, этот метод хорош, если ваш запрос занимает всего несколько миллисекунд и не вызывается много раз из того же потока.
Как их использовать:
var employee = ждать нового EmployeeRepository.GetByIdAsync(1); ---> ваш метод (вызывающий) должен быть здесь также Async, иначе вы должны использовать задачу.
var employee = new EmployeeRepository.GetById(1);
Если ваш класс Repository возвращает IQueryable, вам нужно сделать ToList.First();
Вам нужна инфраструктура Entity Framework 6 или более поздняя =>> поддержка Async. , иначе вы должны сделать это сами!
Пример: предположим, что ваш бизнес-объект:
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();
}
}
Я получаю код soruce от: http://blogs.msdn.com/b/wriju/archive/2013/08/23/using-repository-pattern-in-entity-framework.aspx
Например, для общего репозитория:
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();
}
Где T является базовым объектом для всех ваших объектов. вот полный общий пример: http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle
Для лучшего разделения беспокойства вы также можете комбинировать шаблон хранилища с единицей работы, как описано в книге Мартина Фаулера: http://martinfowler.com/eaaCatalog/unitOfWork.html
Эти две части кода делают разные вещи.
Первая часть находит единое целое.
var user = await new Repo<User>.GetByIdAsync(12);
Вторая часть выполняет предложение where и возвращает первый элемент или null. Он плохо назван, потому что он фактически не вызывает поиск по идентификатору.
var user = new Repo<User>.GetById(u => u.Username=="Bob");
Задача состоит в том, чтобы поддерживать там.NET 4.5 await
и async
команды.
your method(caller) must be here also Async otherwise, you have to use task.
Вы имеете в виду использовать словоawait
?