如何优化 .NET Core 中的 lambda 查询表达式 ?

咨询区

  • Moutia AYED

我的项目需要构建几个图表,产生图表的 数据源 相对比较复杂,参考如下代码:

var resultdb = await  _dbContext.TimeSheetElements
     .Where(t => t.UserId == userId &&
            t.Date.Month == month && 
            t.Date.Year == year)
     .GroupBy(t => t.Date)
     .Select(pc => 
         new ShowPointingChartViewModel
         {
             Day = pc.First().Date.DayOfWeek.ToString(),
             Date = pc.First().Date.ToString(),
             NormalHours = pc.Where(p => p.IsGuard == false && !taskType.Contains(p.UserTask.Type)).Sum(p => p.Duration),
             OutOfBuisnessHours = pc.Where(p => p.IsGuard == true).Sum(p => p.Duration),
             Holidays = pc.Where(p => p.UserTask.Type == "Holiday").Sum(p => p.Duration),
             PublicHolidays = pc.Where(p => p.UserTask.Type == "Public holiday").Sum(p => p.Duration),
             Illness = pc.Where(p => p.UserTask.Type == "Illness").Sum(p => p.Duration),
             GuardFees = pc.Count(p => p.UserTask.Type == "Night Fees"),
             Total = pc.Where(p=>p.UserTask.Type != "Night Fees").Sum(p => p.Duration)
          })
    .ToList();

实际跑起来后,我发现这个 EF 查询语句需要耗费相当长的时间,虽然结果是正确的,但我是一个性能追求者,我想怎么尽可能的对它进行优化,缩短 response 的时间 ?

回答区

  • Eriawan Kusumawardhono

从你的代码看:这个 query 非常复杂,这么重的 query 查询性能必然会低效。

我给出的建议是:你可以先根据一些 where 条件从数据库中预先提取数据,提取完之后,接下来在内存中对这些业务逻辑进行复杂的运算,比如各种 Where,Count 然后再映射到 ShowPointingChartViewModel,参考如下代码:

var resultList = await  _dbContext.TimeSheetElements
   .Where(t => t.UserId == userId && t.Date.Month == month && t.Date.Year == year)
   .GroupBy(t => t.Date).ToList();
var chartViewModel = resultList.Select(pc => 
     new ShowPointingChartViewModel
     {
         Day = pc.First().Date.DayOfWeek.ToString(),
         Date = pc.First().Date.ToString(),
         NormalHours = pc.Where(p => p.IsGuard == false && !taskType.Contains(p.UserTask.Type)).Sum(p => p.Duration),
         OutOfBuisnessHours = pc.Where(p => p.IsGuard == true).Sum(p => p.Duration),
         Holidays = pc.Where(p => p.UserTask.Type == "Holiday").Sum(p => p.Duration),
         PublicHolidays = pc.Where(p => p.UserTask.Type == "Public holiday").Sum(p => p.Duration),
         Illness = pc.Where(p => p.UserTask.Type == "Illness").Sum(p => p.Duration),
         GuardFees = pc.Count(p => p.UserTask.Type == "Night Fees"),
         Total = pc.Where(p=>p.UserTask.Type != "Night Fees").Sum(p => p.Duration)
      })
.ToList();

点评区

说实话,这个问题的优化建议还是值得学习一下的,我个人建议用 SQL Server Profile 或者 Entity Framework 自定的监控方法看看 sql 长啥样,有了这个原始sql,我们就可以进行针对性的优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值