请考虑以下代码段:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
...
}
public class EmployeeRepository<T> : IRepository<T> where T : class
{
private Employee db;
private DbSet<T> dbSet;
public EmployeeRepository()
{
db = new Employee();
dbSet = db.Set<T>();
}
public virtual IQueryable<T> GetAll()
{
return dbSet;
}
}
在控制器中,我将其实现为:
private IRepository<Employee> employeeRepo = null;
public HomeController()
{
employeeRepo = new EmployeeRepository<Employee>();
}
如果我在MVC控制器操作中调用employeeRepo.GetAll()
方法,则使用上面的代码我立即在视图不超过2秒中返回结果,以返回大约500行的记录。如果我将相同的代码更改为
public virtual IEnumerable<T> GetAll()
{
return dbSet.ToList();
}
然后需要 30秒才能从完全相同的表中返回相同数量的行。
所以我的问题是IEnumerable<T>
为什么花费的时间比IQueryable<T>
长得多。
我在网上看到的大部分示例都是使用IEnumerable<T>
存储库模式,所以我不确定我是否使用IQueryable<T>
更新
public ActionResult Index()
{
var allEmployees = employeeRepo.GetAll();
return View(allEmployees);
}
正在执行的SQL是
SELECT EMPLOYEEID, EMPLOYEENAME, EMPLOYEEDOB, EMPLOYEETELEPHONE FROM [DBO].[EMPLOYEE]
返回的确切行数是507.我使用它们全部因为它们会进入下拉列表
答案 0 :(得分:2)
这是因为在Get()
内你调用ToList()
这意味着你实际上是在执行查询。在第一个实现(IQueryable
)中,不执行查询。它将被执行,直到您致电ToList()
答案 1 :(得分:1)
我认为这与提出的问题类似here。 基本上IQueryable将尝试在数据库中执行,因为这是Linq-to-SQL接口,IEnumerable将需要首先将所有内容加载到内存中。 以下是与性能代码差异的另一个detailed explanation。