任务<tentity>做存储库的首选方式</tentity>

时间:2014-05-18 13:36:25

标签: c# .net asp.net-mvc repository-pattern

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让我感到震惊。两者之间哪个更优选?我知道这是一个愚蠢的问题,但它会帮助我更好地理解它们。任何帮助将非常感激。谢谢!

2 个答案:

答案 0 :(得分:1)

这两段代码做了不同的事情。

第一件找到一个实体。

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

第二部分执行where子句并返回第一个元素或null 。它的命名很糟糕,因为它实际上并没有强制按Id进行搜索。

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

该任务是支持.NET 4.5 awaitasync命令。

答案 1 :(得分:1)

首先提出您的问题:

GetByIdAsync :用于从数据库加载数据asynchrone,如果您有大量数据,例如您必须从数据库加载大约10000个条目,那么这个方法将是正确的选择(您也可以使用批量操作)。

GetById :同步加载来自数据库的数据如果您的查询只需要几毫秒而且从同一个线程中不会多次调用,则此方法很有用。

如何使用它们:

var employee = await new EmployeeRepository.GetByIdAsync(1); ---&gt;你的方法(调用者)必须在这里也是异步,否则你必须使用任务。

var employee = new EmployeeRepository.GetById(1);

如果您的Repository类返回IQueryable,那么您必须执行ToList.First();

您需要实体框架6或更高版本=&gt;&gt;支持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

为了更好地分离关注点,您还可以将存储库模式与Martin Fowler所描述的工作单元结合起来: http://martinfowler.com/eaaCatalog/unitOfWork.html