我使用的是带有Generic Repository、AutoMapper和UnitOfWork的Entity Framework 6。当我使用远程数据库(VPN连接(时,查找方法的执行速度似乎非常慢。
通用存储库接口:
public interface IRepository<T, T1>
where T : class, IEntity
where T1 : class, IEntity
{
....
List<T1> Find(Expression<Func<T1, bool>> predicate);
}
}
Generic Repository Find方法的实现我尝试了两个选项,似乎第二个选项花费的时间较少,但还不够(~7分钟,第一个选项~10分钟(
public List<T1> Find(Expression<Func<T1, bool>> predicate)
{
var listT1 = AutoMapperConfiguration.GetMapperConfiguration().Map<List<T1>>(_dbContext.Set<T>().Where(q => !q.IsDeleted));
var result = listT1.Where(predicate.Compile()).ToList();
return result;
}
public List<T1> Find(Expression<Func<T1, bool>> predicate)
{
var query = _dbContext.Set<T>().Where(q => !q.IsDeleted);
return AutoMapperConfiguration.GetMapperConfiguration().Map<List<T1>>(query).AsQueryable().Where(predicate).ToList();
}
在控制器中,我像这个一样使用它
public PrjUser_ViewModel GetUserByName(string name)
{
using (var unitOfWork = _unitOfWorkFactory.Create())
{
return unitOfWork.PrjUsers.Find(user => user.Name.ToUpper() == name.ToUpper()).FirstOrDefault();
}
}
以及在uow实现中:
public IRepository<PrjUser, PrjUser_ViewModel> PrjUsers
{
get
{
var _prjusers = new Repository<PrjUser, PrjUser_ViewModel>(_databaseContext);
_prjusers.ResetIndexes();
return _prjusers;
}
}
我可以做些什么来改进find方法的执行?
这两个版本的代码基本上都是从数据库下载整个用户列表,并在内存中进行过滤,这就是它们速度慢的原因。
在您的第一个版本中,将谓词移动到查询中,例如:
public List<T1> Find(Expression<Func<T1, bool>> predicate)
{
// Note this is still an IQueryable<T> so nothing is executed against the database yet
var query = _dbContext.Set<T>()
.Where(q => !q.IsDeleted)
.Where(predicate);
return AutoMapperConfiguration.GetMapperConfiguration()
.Map<List<T1>>(query);
}