标签:
首先说明下:
第一次运行真是太慢了,处理9600多个员工数据,用了81分钟!!
代码也挺简单,主要是得到数据--》对比分析--》插入分析结果到数据库。用的是EF的操作模式。
public void AllocateAllPlans() { var employees = _efWorker.EmployeeRepository.FindAll(filter: p => p.Status.Trim().ToUpper() == "ACTIVE"); var plans = _efWorker.BenefitPlanRepository.FindAll(includeProperties: "PlanEligibility", orderBy: query => query.OrderBy(p => p.Priority), filter: p => p.Status.Trim().ToUpper() == "ACTIVE"); if (employees == null || plans == null) return; AllocatePlanForEmployee(employees, plans); _efWorker.SaveChanges(); } /// <summary> /// 根据输入员工和计划,生成PlanEntitlement以及Account初始数据 /// </summary> /// <param name="employees"></param> /// <param name="plans"></param> public void AllocatePlanForEmployee(IEnumerable<Employee> employees, IEnumerable<BenefitPlan> plans) { //初始化员工积分账户,默认积分为0 AccountingHelper accountingHelper = new AccountingHelper(_efWorker); foreach (var employee in employees) { //先验证业务逻辑相关基本信息 List<string> errorMsg; if (!_insuredInfoValidator.ValidateEmployeeInfo(employee, out errorMsg)) throw new Exception(string.Join(@"\n", errorMsg.ToArray())); bool joinedPlan = false; foreach (var plan in plans) { var eligibilitys = plan.PlanEligibility; if (_eligibilityEvaluator.MatchPlan(employee, eligibilitys)) { //添加该员工与计划的对应数据到表PlanEntitlement var planEntitlement = new PlanEntitlement { Id = Guid.NewGuid(), PlanId = plan.Id, EmployeeId = employee.Id, JoinPlanDate = DateTime.Now, //SelectionOpenDate = plan.SelectionOpenDate, //SelectionCloseDate = plan.SelectionCloseDate, Status = "ACTIVE" }; _efWorker.PlanEntitlementRepository.Insert(planEntitlement); accountingHelper.InitAccount(planEntitlement.Id, employee.Id, 0m, "EE"); joinedPlan = true; break;//根据优先级,员工分配到一个计划就跳出计划匹配循环 } } if (joinedPlan == false) { throw new Exception("Employee not match any plan,EmployeeId=" + employee.Id.ToString()); } } }
代码写得丑,大家将就看,有什么改进建议请提出。多谢指教!
第一次优化是把查询出来的原始数据跟踪去掉:
public IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "") { IQueryable<TEntity> query = dbSet; if(filter!=null) { query = query.Where(filter); } foreach(var includeProperty in includeProperties.Split(new char[]{‘,‘},StringSplitOptions.RemoveEmptyEntries)) { query = query.Include(includeProperty); } if(orderBy!=null) { return orderBy(query).AsQueryable().AsNoTracking().ToList();//这里之前没有添加AsNoTracking()方法 } else { return query.AsQueryable().AsNoTracking().ToList();//这里之前没有添加AsNoTracking()方法 } }
看注释,就改动了下获取数据集的方法,同样多的数据,执行完毕只花了12分钟。
81分钟的图就不贴出来了,跑81分钟个太坑了。
12分钟还是太慢,看了各位大大的博客,于是准备再把插入数据那段优化下。
http://www.cnblogs.com/linfei721/archive/2013/06/07/3123579.html
public void AllocateAllPlans() { var employees = _efWorker.EmployeeRepository.FindAll(filter: p => p.Status.Trim().ToUpper() == "ACTIVE"); var plans = _efWorker.BenefitPlanRepository.FindAll(includeProperties: "PlanEligibility", orderBy: query => query.OrderBy(p => p.Priority), filter: p => p.Status.Trim().ToUpper() == "ACTIVE"); if (employees == null || plans == null) return; _efWorker.context.Configuration.AutoDetectChangesEnabled = false;//设置不跟踪标记 AllocatePlanForEmployee(employees, plans); _efWorker.SaveChanges(); }
依葫芦画瓢,先改了试试看。
!!!果然拖拉机变灰机了。
只用了8秒,有图有真相啊。等等,先去检查下数据正确不。
看起来数据没有问题。
总结:
.AsNoTracking()和context.Configuration.AutoDetectChangesEnabled = false这两个设置都是让EF不对当前的数据集做变化跟踪,因此如果在数据集需要做更新或者删除操作时,这两个方法不能用,当然可以根据业务需求,灵活使用它们。
标签:
原文地址:http://www.cnblogs.com/tylertang/p/4929308.html