ef core linq 优化

 

一、新增

  1. 先校验参数
  2. db查询所需要的基础数据
  3. 基础数据非空验证
  4. 组装Entity报错
           /// <summary>
            /// 新增数据
            /// </summary>
            /// <returns></returns>
            public async Task AddAsync(CreateOrderRequest request)
            {
                _ = request.Order ?? throw new UserFriendlyException("order is null");
                _ = request.Items ?? throw new UserFriendlyException("items is null");
    
                if (!request.Items.Any())
                    throw new UserFriendlyException("items is null");
    
                //职责单一,只进行参数数据校验
                foreach (var salesOrderDetail in request.Items)
                {
                    if (salesOrderDetail.SaleNum <= 0)
                        throw new UserFriendlyException("error");
    
                    if (salesOrderDetail.GoodsId.Equals(default))
                        throw new UserFriendlyException("error");
    
                    if (salesOrderDetail.ExpressMoney < 0)
                        throw new UserFriendlyException("error");
                }
    
                var goodsIds = request.Items.Select(item => item.GoodsId);
                //只查询使用到的字段
                var goods = _secDbContext.Goods.Where(good => goodsIds.Contains(good.Id)).Select(good => new
                {
                    good.Title,
                    good.Id,
                    good.Inventory,
    
                }).ToList();
    
                //职责单一,只进行基础数据校验
                foreach (var salesOrderDetail in request.Items)
                {
                    var good = goods.Find(good => good.Id == salesOrderDetail.GoodsId);
                    if (good == null)
                        throw new UserFriendlyException("商品不存在");
    
                    if (good.Inventory < salesOrderDetail.SaleNum)
                        throw new UserFriendlyException("库存不足");
                }
    
                var order = new Mapping<SalesOrder, SalesOrder>().ReverseMap(request.Order);
                var orderItems = request.Items.Select(item =>
                {
                    return new Mapping<SalesOrderDetail, SalesOrderDetail>().ReverseMap(item);
                });
    
                await _secDbContext.AddAsync(order);
                await _secDbContext.AddRangeAsync(orderItems);
    
            }

二、查询优化

  1. FirstOrDefaultAsync 和 FindAsync 区别
    1. FirstOrDefaultAsync (表达树)直接查询数据     PS:两个方法同时查询了一条数据,进行Update 会提示异常:xxxxx Id 重复
    2. FindAsync  (主键Id)会先默认查询DbContext缓存,查不到查询数据 PS:两个方法同时查询了一条数据,公用一条 数据缓存
    3. 判断数据库是否存在某条数据时,请使用Any(),不要使用Count()
    4. Where查询不要有转换语句:where(x = x.CteateTime > = new DateTime(""))
  2. Linq 优化
    1. 查询方式
            var orders = _secDbContext.SalesOrders.Take(10).ToList();

            //低级的错误
            foreach (var item in orders)
            {
                var salesOrderDetail = await _secDbContext.SalesOrderDetails.FirstOrDefaultAsync(details=>details.SalesOrderId==item.Id);
                //TODO:业务逻辑
            }

            //正确写法
            var orderIds = orders.Select(order => order.Id);
            var salesOrderDetails = _secDbContext.SalesOrderDetails.Where(details => orderIds.Contains(details.SalesOrderId)).ToList();
            //TODO:业务逻辑

      2.连表查询优化

      1. 感觉Linq写的不好可以先写Sql分析执行计划和效率,借助SQL转Linq工具的使用——Linqerhttp://www.sqltolinq.com/
      2.  有数据量比较大的表尽量不要使用 left join,索引掌控不好会导致全表扫描(表结构数据大会很明显效率下降)
      3. 百度ef core linq 优化

         

 

三、更新

  1. 表结构添加版本号(乐观锁)
  2. 只更新指定字段(EF Core 默认有这个功能,需要先查出来数据)PS:this.ChangeTracker.AutoDetectChangesEnabled = false; 会导致此功能失效
  3. 不查询更新
  4.           db.Set<T>().Attach(entity);//将数据用未更改的状态放在上下文中,相当于从数据库读取了该实体
    
                entity.ModifyDate = DateTime.Now;
                entity.ModifyId = loginUser.Id;
                entity.ModifyName = loginUser.UserName;
    
                db.Entry(entity).State = EntityState.Modified;
                db.Entry(entity).Property("CreateId").IsModified = false;
                db.Entry(entity).Property("CreateName").IsModified = false;
                db.Entry(entity).Property("CreateDate").IsModified = false;
    
               db.SaveChanges();

     

  

写代码注意细节,时刻想着还有咩有优化空间,如何写到最优,而不是实现了能用就行。

 

上一篇:Activiti5 数据库表结构


下一篇:IfcMaterialList