项目背景WMS  智能仓储管理系统:

1.实现简单的增删改查:


1.1. Entities:

using Qhbx.Tibet.Wms.Core.EnumDefinitions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;namespace Qhbx.Tibet.Wms.Entities.Basic
{/// <summary>/// 货物信息/// </summary>[Table("bx_wms_goods")]public class GoodsEntity : Entity{/// <summary>/// 货物类别/// </summary>[Required][StringLength(32)][Description("货物类别")]public string GcId { get; set; }/// <summary>/// 货物编号/// </summary>[Required][StringLength(32)][Description("货物编号"), UniqueIndexKey]public string GoodsCode { get; set; }/// <summary>/// 货物名称/// </summary>[Required][StringLength(100)][Description("货物名称")]public string GoodsName { get; set; }/// <summary>/// 内包装数量/// </summary>[Description("内包装数量")]public double InnerPackingQuantity { get; set; }/// <summary>/// 内包装货物体积/// </summary>[Description("内包装货物体积")]public double InnerPackingVolume { get; set; }/// <summary>/// 内包装货物重量/// </summary>[Description("内包装货物重量")]public double InnerPackingWeight { get; set; }/// <summary>/// 材质/// </summary>[StringLength(32)][Description("材质")]public string Material { get; set; }/// <summary>/// 最大库存量/// </summary>[Description("最大库存量")]public double MaxStock { get; set; }/// <summary>/// 最小库存量/// </summary>[Description("最小库存量")]public double MinStock { get; set; }/// <summary>/// 外包装数量/// </summary>[Description("外包装数量")]public double OuterPackingQuantity { get; set; }/// <summary>/// 外包装货物重量/// </summary>[Description("外包装货物重量")]public double OuterPackingWeight { get; set; }/// <summary>/// 价格/// </summary>[Description("价格")]public double Price { get; set; }/// <summary>/// 重量/// </summary>[Description("重量")]public double Weight { get; set; }/// <summary>/// 保质期/// </summary>[Description("保质期")]public double ShelfLife { get; set; }/// <summary>/// 规格/// </summary>[Required][StringLength(50)][Description("规格")]public string Specs { get; set; }/// <summary>/// 供应商编号/// </summary>[Required][StringLength(32)][Description("供应商编号")]public string SupplierId { get; set; }/// <summary>/// 状态/// </summary>[Description("状态(0启用1禁用)")]public override Status Status { get; set; }/// <summary>/// 是否删除(0未删除1已删除)/// </summary>[Description("是否删除(0未删除1已删除)")]public override DeleteStatus IsDelete { get; set; }/// <summary>/// 创建人/// </summary>[StringLength(32)][Description("创建人")]public override string Creator { get; set; }/// <summary>/// 创建时间/// </summary>[Description("创建时间")]public override DateTime CreateDate { get; set; }/// <summary>/// 编辑人/// </summary>[StringLength(32)][Description("编辑人")]public override string Updator { get; set; }/// <summary>/// 编辑时间/// </summary>[Description("编辑时间")]public override DateTime UpdateDate { get; set; }}
}
using Qhbx.Common.Core;
using Qhbx.Tibet.Wms.Core.EnumDefinitions;
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;namespace Qhbx.Tibet.Wms.Entities
{/// <summary>/// 实体类基类/// </summary>public abstract class Entity : IMapper{/// <summary>/// 编号/// </summary>[Key][Required][StringLength(32)][Description("编号")]public virtual string Id { get; set; }/// <summary>/// 状态/// </summary>public virtual Status Status { get; set; }/// <summary>/// 是否删除(0未删除1已删除)/// </summary>public virtual DeleteStatus IsDelete { get; set; }/// <summary>/// 创建人id/// </summary>[StringLength(32)]public virtual string Creator { get; set; }/// <summary>/// 创建时间/// </summary>public virtual DateTime CreateDate { get; set; }/// <summary>/// 编辑人id/// </summary>[StringLength(32)]public virtual string Updator { get; set; }/// <summary>/// 编辑时间/// </summary>public virtual DateTime UpdateDate { get; set; }}
}

1.2 Model:

using Qhbx.Common.Core;
using Qhbx.Tibet.Wms.Core.EnumDefinitions;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;namespace Qhbx.Tibet.Wms.Models.Basic
{/// <summary>/// 货物信息的模型/// </summary>public class GoodsModel: IMapper{/// <summary>/// 编号/// </summary>[Key][MaxLength(32, ErrorMessage = "编号的最大长度是32")]public virtual string Id { get; set; }/// <summary>/// 货物类别/// </summary>[Required][MaxLength(32, ErrorMessage = "货物类别的最大长度是32")]public string GcId { get; set; }/// <summary>/// 货物类别名称/// </summary>public string GcName { get; set; }/// <summary>/// 货物编号/// </summary>[Required][MaxLength(32, ErrorMessage = "货物编号的最大长度是32")]public string GoodsCode { get; set; }/// <summary>/// 货物名称/// </summary>[Required][MaxLength(100, ErrorMessage = "货物名称的最大长度是100")]public string GoodsName { get; set; }/// <summary>/// 内包装数量/// </summary>public double InnerPackingQuantity { get; set; }/// <summary>/// 内包装货物体积/// </summary>public double InnerPackingVolume { get; set; }/// <summary>/// 内包装货物重量/// </summary>public double InnerPackingWeight { get; set; }/// <summary>/// 材质/// </summary>[MaxLength(32, ErrorMessage = "材质的最大长度是32")]public string Material { get; set; }/// <summary>/// 最大库存量/// </summary>public double MaxStock { get; set; }/// <summary>/// 最小库存量/// </summary>public double MinStock { get; set; }/// <summary>/// 外包装数量/// </summary>public double OuterPackingQuantity { get; set; }/// <summary>/// 外包装货物重量/// </summary>public double OuterPackingWeight { get; set; }/// <summary>/// 价格/// </summary>public double Price { get; set; }/// <summary>/// 重量/// </summary>public double Weight { get; set; }/// <summary>/// 保质期/// </summary>public double ShelfLife { get; set; }/// <summary>/// 规格/// </summary>[Required][MaxLength(50, ErrorMessage = "规格的最大长度是50")]public string Specs { get; set; }/// <summary>/// 供应商编号/// </summary>[Required][MaxLength(32)]public string SupplierId { get; set; }/// <summary>/// 供应商名称/// </summary>public string SupplierName { get; set; }/// <summary>/// 状态(0启用,1禁用)/// </summary>[Range(0, 1, ErrorMessage = "{0}只能是0或者1【0启用,1禁用】")]public Status Status { get; set; }/// <summary>/// 状态名称/// </summary>public string StatusText => this.Status.GetDescription();/// <summary>/// 是否删除(0未删除1已删除)/// </summary>[Range(0, 1, ErrorMessage = "{0}值只能是0或者1【0未删除,1已删除】")]public DeleteStatus IsDelete { get; set; }/// <summary>/// 状态名称/// </summary>public string IsDeleteText => this.IsDelete.GetDescription();/// <summary>/// 创建人/// </summary>[MaxLength(32, ErrorMessage = "创建人的最大长度是32")]public string Creator { get; set; }/// <summary>/// 创建时间/// </summary>public DateTime CreateDate { get; set; }/// <summary>/// 编辑人/// </summary>[MaxLength(32, ErrorMessage = "编辑人的最大长度是32")]public string Updator { get; set; }/// <summary>/// 编辑时间/// </summary>public DateTime UpdateDate { get; set; }}
}

1.3 API-Controllers

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Qhbx.Common.Core;
using Qhbx.Tibet.Wms.Api.Filters;
using Qhbx.Tibet.Wms.Api.Models;
using Qhbx.Tibet.Wms.Core;
using Qhbx.Tibet.Wms.Entities.Basic;
using Qhbx.Tibet.Wms.IServices.Basic;
using Qhbx.Tibet.Wms.Models;
using Qhbx.Tibet.Wms.Models.Basic;namespace Qhbx.Tibet.Wms.Api.Controllers
{/// <summary>/// 货物/// </summary>[Route("api/[controller]/[action]")][ApiController][Authorize][FunctionAuthorize(FunctionConst.GoodsFuncCode)]public class GoodsController : ControllerBase{private IGoodsService _service { get; }private ILogger _log { get; }/// <summary>/// 构造函数/// </summary>/// <param name="service"></param>/// <param name="logger"></param>public GoodsController(IGoodsService service, ILogger<GoodsController> logger){_service = service;_log = logger;}/// <summary>/// 获取货物列表分页数据/// </summary>/// <param name="pageIndex">页码</param>/// <param name="pageSize">每页显示条数</param>/// <param name="key">查询条件(货物编号、货物名称、货物类别、供应商编号)</param>/// <returns></returns>[HttpGet][Log("获取货物列表分页数据")]public Page<GoodsModel> GetPageList(int pageIndex = 1, int pageSize = 10, string key = ""){return  _service.GetPageList(pageIndex, pageSize, key);}/// <summary>/// 获取货物列表数据/// </summary>/// <param name="key">查询条件(Name或Code或Id)</param>/// <returns></returns>[HttpGet][Log("获取货物列表数据")]public async Task<List<GoodsModel>> GetList(string key = ""){return await _service.GetList(key);}/// <summary>/// 添加货物信息/// </summary>/// <param name="model"></param>/// <returns></returns>[HttpPost][Log("添加货物信息")]public async Task<IActionResult> Add(GoodsModel model){model.Id = GuidUtil.FormatN();model.Creator = User.GetUserId();model.CreateDate = System.DateTime.Now;model.UpdateDate = System.DateTime.Now;model.Updator = User.GetUserId();await _service.AddAsync(model);return Ok();}/// <summary>/// 更新货物信息/// </summary>/// <param name="model"></param>/// <returns></returns>[HttpPost][Log("更新货物信息")]public async Task<IActionResult> Edit(GoodsModel model){model.UpdateDate = System.DateTime.Now;model.Updator = User.GetUserId();await _service.EditAsync(model);return Ok();}/// <summary>/// 批量删除货物信息/// </summary>/// <param name="ids">主键ID</param>/// <returns></returns>[HttpDelete][Log("删除货物信息")]public async Task<IActionResult> Delete(string[] ids){var updator = User.GetUserId();await _service.DeleteAsync(ids, updator);return Ok();}}
}

1.4  IService

using Qhbx.Tibet.Wms.Entities.Basic;
using Qhbx.Tibet.Wms.Models;
using Qhbx.Tibet.Wms.Models.Basic;
using System.Collections.Generic;
using System.Threading.Tasks;namespace Qhbx.Tibet.Wms.IServices.Basic
{/// <summary>/// 货物的服务接口/// </summary>public interface IGoodsService : IService<GoodsEntity>{/// <summary>/// 获取货物列表分页数据/// </summary>/// <param name="pageIndex">页码</param>/// <param name="pageSize">每页显示条数</param>/// <param name="key">查询条件货(物编号、货物名称、货物类别、供应商编号)</param>/// <returns></returns>Page<GoodsModel> GetPageList(int pageIndex = 1, int pageSize = 10, string key = "");/// <summary>/// 获取货物列表数据/// </summary>/// <param name="key">查询条件</param>/// <returns></returns>Task<List<GoodsModel>> GetList(string key = "");/// <summary>/// 添加货物信息/// </summary>/// <param name="model"></param>/// <returns></returns>Task AddAsync(GoodsModel entity);/// <summary>/// 更新货物信息/// </summary>/// <param name="model"></param>/// <returns></returns>Task EditAsync(GoodsModel entity);/// <summary>/// 批量删除货物信息/// </summary>/// <param name="id"></param>/// <returns></returns>Task DeleteAsync(string[] ids,string updator);}
}

1.5 Service

using Microsoft.EntityFrameworkCore;
using Qhbx.Common.Core;
using Qhbx.Tibet.Wms.Core.EnumDefinitions;
using Qhbx.Tibet.Wms.Entities.Basic;
using Qhbx.Tibet.Wms.IServices;
using Qhbx.Tibet.Wms.IServices.Basic;
using Qhbx.Tibet.Wms.Models;
using Qhbx.Tibet.Wms.Models.Basic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;namespace Qhbx.Tibet.Wms.Services.Basic
{/// <summary>/// 货物的服务基类/// </summary>public class GoodsService : IGoodsService{/// <summary>/// 构造方法/// </summary>/// <param name="dbContext"></param>public GoodsService(DbContext dbContext, AutoMapper.IMapper mapper){Context = dbContext;Mapper = mapper;}/// <summary>/// 数据库上下文/// </summary>public DbContext Context { get; set; }public AutoMapper.IMapper Mapper { get; set; }/// <summary>/// 添加货物信息/// </summary>/// <param name="model"></param>/// <returns></returns>public async Task AddAsync(GoodsModel model){if (await this.ContainsAsync(x => x.GoodsCode == model.GoodsCode && x.IsDelete == DeleteStatus.Normal)){throw new CustomException($"货物编号【{model.GoodsCode}】已存在");}if (await this.ContainsAsync(x => x.GoodsName == model.GoodsName.Trim() && x.IsDelete == DeleteStatus.Normal)){throw new CustomException($"货物名称【{model.GoodsName}】已存在");}var entity = Mapper.Map<GoodsEntity>(model);await this.InsertAsync(entity);}/// <summary>/// 修改货物信息/// </summary>/// <param name="entity"></param>/// <returns></returns>public async Task EditAsync(GoodsModel model){if (await this.Context.Set<GoodsEntity>().CountAsync(x => x.Id == model.Id && x.IsDelete == DeleteStatus.Normal) > 0){if (await this.ContainsAsync(x => x.GoodsCode == model.GoodsCode && x.Id != model.Id && x.IsDelete == DeleteStatus.Normal)){throw new CustomException($"货物编号【{model.GoodsCode}】已存在");}if (await this.ContainsAsync(x => x.GoodsName == model.GoodsName.Trim() && x.Id != model.Id && x.IsDelete == DeleteStatus.Normal)){throw new CustomException($"货物名称【{model.GoodsName}】已存在");}var entity = Mapper.Map<GoodsEntity>(model);await this.UpdateAsync(entity);}else{throw new CustomException("该货物不存在!");}}/// <summary>/// 获取货物列表分页数据/// </summary>/// <param name="pageIndex">页码</param>/// <param name="pageSize">每页显示条数</param>/// <param name="key">查询条件(货物编号、货物名称、货物类别、供应商编号)</param>/// <returns></returns>public Page<GoodsModel> GetPageList(int pageIndex = 1, int pageSize = 10, string key = ""){Expression<Func<GoodsEntity, bool>> predicate = e => e.IsDelete == DeleteStatus.Normal;if (!string.IsNullOrWhiteSpace(key))predicate = predicate.And(x => x.GoodsCode.Contains(key) || x.GoodsName.Contains(key) || x.GcId.Contains(key) || x.SupplierId.Contains(key));var goods = from good in this.Context.Set<GoodsEntity>().Where(predicate)join supplier in this.Context.Set<SupplierEntity>() on good.SupplierId equals supplier.Id into suppliersfrom supplierDefault in suppliers.DefaultIfEmpty()join dic in this.Context.Set<DictionaryEntity>() on good.GcId equals dic.Id into dicsfrom dicDefault in dics.DefaultIfEmpty()select new GoodsModel{Id = good.Id,GcId = good.GcId,GcName = dicDefault.Name,GoodsCode = good.GoodsCode,GoodsName = good.GoodsName,InnerPackingQuantity = good.InnerPackingQuantity,InnerPackingVolume = good.InnerPackingVolume,InnerPackingWeight = good.InnerPackingWeight,Material = good.Material,MaxStock = good.MaxStock,MinStock = good.MinStock,OuterPackingQuantity = good.OuterPackingQuantity,OuterPackingWeight = good.OuterPackingWeight,Price = good.Price,Weight = good.Weight,ShelfLife = good.ShelfLife,Specs = good.Specs,SupplierId = good.SupplierId,SupplierName = supplierDefault.SupplierName,Status = good.Status,IsDelete = good.IsDelete,Creator = good.Creator,CreateDate = good.CreateDate,Updator = good.Updator,UpdateDate = good.UpdateDate};if (pageIndex <= 0) pageIndex = 1;if (pageSize <= 0) pageSize = 10;IEnumerable<GoodsModel> datas = goods.OrderByDescending(g => g.UpdateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize);Page<GoodsModel> page = new Page<GoodsModel> { Index = pageIndex, Size = pageSize, Datas = datas, Amount = goods.Count() };return page;}/// <summary>/// 获取货物列表数据/// </summary>/// <param name="key">查询条件(Name或Code或Id)</param>/// <returns></returns>public async Task<List<GoodsModel>> GetList(string key = ""){Expression<Func<GoodsEntity, bool>> predicate = e => e.IsDelete == DeleteStatus.Normal;if (!string.IsNullOrWhiteSpace(key)){predicate = predicate.And(e => e.GoodsName.Contains(key) || e.GoodsCode.Contains(key) || e.Id == key);}var result = await this.WhereAsync(predicate);var list = Mapper.Map<List<GoodsModel>>(result);return list;}/// <summary>/// 批量删除货物信息/// </summary>/// <param name="models"></param>/// <returns></returns>public async Task DeleteAsync(string[] ids, string updator){var goodss = await this.WhereAsync(a => ids.Contains(a.Id) && a.IsDelete == Core.EnumDefinitions.DeleteStatus.Normal);if (goodss.Count() == 0){throw new CustomException("货物信息已经被删除,或者不存在!");}goodss = goodss.Select(a => { a.IsDelete = Core.EnumDefinitions.DeleteStatus.HasDelete; a.UpdateDate = DateTime.Now; a.Updator = updator; return a; });foreach (var goods in goodss){await this.UpdateIncludeAsync(goods, a => new { a.IsDelete, a.UpdateDate, a.Updator });}}}
}

1.6 更新该实例的指定属性 的方法

/// <summary>/// 更新该实例的指定属性/// </summary>/// <typeparam name="Tproperty">属性类型</typeparam>/// <typeparam name="TEntity">实例类型</typeparam>/// <param name="sender"></param>/// <param name="entity">要更新的实例</param>/// <param name="propertys">要更新的属性</param>/// <returns></returns>public static async Task<int> UpdateIncludeAsync<Tproperty, TEntity>(this IService<TEntity> sender, TEntity entity, Expression<Func<TEntity, Tproperty>> propertys)where TEntity : class{if (propertys == null) return default;var entry = sender.Context.Entry<TEntity>(entity);var propertyNames = propertys.GetPropertys();foreach (var propName in propertyNames){entry.Property(propName).IsModified = true;}return await sender.Context.SaveChangesAsync();}

2.一次性获取 1:多(入库单:入库单明细)信息 集合 使用GroupJoin对主子表集合进行关联
2.1一次性获取 1:多(入库单:入库单明细)信息  [先查主表,然后对主表进行分页,再通过主表分页后的数据获取其入库单明细信息,最后使用GroupJoin对主子表集合进行关联]

            Expression<Func<InStockDemandBillEntity, bool>> predicate = e => e.IsDelete == DeleteStatus.Normal;if (!string.IsNullOrWhiteSpace(key))predicate = predicate.And(x => x.DemandNo.Contains(key) || x.Id.Contains(key) || x.SupplierId.Contains(key));if (inStatus >= 0)predicate = predicate.And(x => x.InStockStatus == (InStockStatus)inStatus);//Enum的Equals不会转换为SQL语句if (planStartDate != null)predicate = predicate.And(x => x.PlanArrivalTime >= ConvertHelper.ConvertToDateTime((long)planStartDate));if (planEndDate != null)predicate = predicate.And(x => x.PlanArrivalTime <= ConvertHelper.ConvertToDateTime((long)planEndDate));if (actualStartDate != null)predicate = predicate.And(x => x.ActualArrivalTime >= ConvertHelper.ConvertToDateTime((long)actualStartDate));if (actualEndDate != null)predicate = predicate.And(x => x.ActualArrivalTime <= ConvertHelper.ConvertToDateTime((long)actualEndDate));//入库单信息var inStocks = from instock in this.Context.Set<InStockDemandBillEntity>().Where(predicate)join supplier in this.Context.Set<SupplierEntity>() on instock.SupplierId equals supplier.Id into suppliersfrom supplierDefault in suppliers.DefaultIfEmpty()join area in this.Context.Set<WareHouseAreaEntity>() on instock.AreaId equals area.Id into areasfrom areaDefault in areas.DefaultIfEmpty()join dic in this.Context.Set<DictionaryEntity>() on instock.InstockGroup equals dic.Id into dicsfrom dicInstockGroup in dics.DefaultIfEmpty()join dic_a in this.Context.Set<DictionaryEntity>() on instock.ActualInstockGroup equals dic_a.Id into dic_asfrom dicActualInstockGroup in dic_as.DefaultIfEmpty()join dic_i in this.Context.Set<DictionaryEntity>() on instock.InstockNature equals dic_i.Id into dic_isfrom dicInstockNature in dic_is.DefaultIfEmpty()select new InStockDemandBillModel{Id = instock.Id,DemandNo = instock.DemandNo,InstockGroup = instock.InstockGroup,InstockGroupName = dicInstockGroup.Name,OrderNo = instock.OrderNo,PlanArrivalTime = instock.PlanArrivalTime,ActualArrivalTime = instock.ActualArrivalTime,ActualInstockGroup = instock.ActualInstockGroup,ActualInstockGroupName = dicActualInstockGroup.Name,DeliveryCompany = instock.DeliveryCompany,DeliveryMan = instock.DeliveryMan,Status = instock.Status,InStockStatus = instock.InStockStatus,SupplierId = instock.SupplierId,SupplierName = supplierDefault.SupplierName,VehicleNo = instock.VehicleNo,InstockNature = instock.InstockNature,InstockNatureName = dicInstockNature.Name,GroundingGroup = instock.GroundingGroup,AppointmentUser = instock.AppointmentUser,AppointmentDate = instock.AppointmentDate,CheckUser = instock.CheckUser,CheckTime = instock.CheckTime,TaskUser = instock.TaskUser,TaskTime = instock.TaskTime,AreaId = instock.AreaId,AreaName = areaDefault.AreaName,IsDelete = instock.IsDelete,Creator = instock.Creator,CreateDate = instock.CreateDate,Updator = instock.Updator,UpdateDate = instock.UpdateDate};if (pageIndex <= 0) pageIndex = 1;if (pageSize <= 0) pageSize = 10;IEnumerable<InStockDemandBillModel> datas = inStocks.OrderByDescending(g => g.UpdateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize);Page<InStockDemandBillModel> page = new Page<InStockDemandBillModel> { Index = pageIndex, Size = pageSize, Datas = datas.ToList(), Amount = inStocks.Count() };//入库单明细信息var inStockItems = from instockItem in this.Context.Set<InStockDemandBillItemEntity>()join goods in this.Context.Set<GoodsEntity>() on instockItem.GoodsId equals goods.Id into goodsesfrom good in goodses.DefaultIfEmpty()join unloadwayDic in this.Context.Set<DictionaryEntity>() on instockItem.UnloadWay equals unloadwayDic.Id into unloadwaysfrom unloadway in unloadways.DefaultIfEmpty()select new InStockDemandBillItemModel{Id = instockItem.Id,InstockDemandBillId = instockItem.InstockDemandBillId,PlanArrivalQuantity = instockItem.PlanArrivalQuantity,ProductBatch = instockItem.ProductBatch,ActualArrivalQuantity = instockItem.ActualArrivalQuantity,ActualProductBatch = instockItem.ActualProductBatch,GoodsId = instockItem.GoodsId,GoodsName = good.GoodsName,PackingSpecs = instockItem.PackingSpecs,UnloadWay = instockItem.UnloadWay,UnloadWayName = unloadway.Name,IsDelete = instockItem.IsDelete,Creator = instockItem.Creator,CreateDate = instockItem.CreateDate,Updator = instockItem.Updator,UpdateDate = instockItem.UpdateDate};page.Datas = page.Datas.GroupJoin<InStockDemandBillModel, InStockDemandBillItemModel, string, InStockDemandBillModel>(inStockItems, idb => idb.Id, isdbtm => isdbtm.InstockDemandBillId, (instock, instockbillitems) =>{InStockDemandBillModel inStockDemandBillModel = instock;inStockDemandBillModel.InStockItems = instockbillitems;return inStockDemandBillModel;});return page;

2.2 多表同时添加 采用事务处理

 /// <summary>/// 添加入库单/// </summary>/// <param name="inStockModel"></param>/// <returns></returns>public async Task AddAsync(InStockDemandBillModel inStockModel){if (inStockModel.AppointmentDate.Date < DateTime.Now.Date){throw new CustomException("预约日期不能小于当前日期");}if (inStockModel.PlanArrivalTime < System.DateTime.Now){throw new CustomException("计划到货时间不能小于当前时间");}//入库单 数据添加var inStockEntity = Mapper.Map<InStockDemandBillEntity>(inStockModel);inStockEntity.Id = GuidUtil.FormatN();inStockEntity.DemandNo = CommonConst.RK.CreateBillCode();this.Context.Set<InStockDemandBillEntity>().Add(inStockEntity);//入库明细 数据添加foreach (var item in inStockModel.InStockItems){var inStockItemEntity = Mapper.Map<InStockDemandBillItemEntity>(item);inStockItemEntity.Id = GuidUtil.FormatN();inStockItemEntity.InstockDemandBillId = inStockEntity.Id;this.Context.Set<InStockDemandBillItemEntity>().Add(inStockItemEntity);}//事务处理var tran = this.Context.Database.BeginTransaction();try{await this.Context.SaveChangesAsync();tran.Commit();}catch (Exception ex){tran.Rollback();throw new CustomException($"添加入库单信息异常,异常信息:" + ex.Message);}}

3.其他代码段:

using Microsoft.EntityFrameworkCore;
using Qhbx.Common.Core;
using Qhbx.Tibet.Wms.Core;
using Qhbx.Tibet.Wms.Core.EnumDefinitions;
using Qhbx.Tibet.Wms.Entities.Basic;
using Qhbx.Tibet.Wms.Entities.OutStock;
using Qhbx.Tibet.Wms.Entities.Stock;
using Qhbx.Tibet.Wms.IServices;
using Qhbx.Tibet.Wms.IServices.OutStock;
using Qhbx.Tibet.Wms.IServices.Stock;
using Qhbx.Tibet.Wms.Models;
using Qhbx.Tibet.Wms.Models.OutStock;
using Qhbx.Tibet.Wms.Models.Stock;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;namespace Qhbx.Tibet.Wms.Services.OutStock
{/// <summary>/// 出库单接口实现类/// </summary>public class OutStockService : IOutStockService{public OutStockService(DbContext dbContext, AutoMapper.IMapper mapper,IStockService stockService){Context = dbContext;Mapper = mapper;_stockService = stockService;}public DbContext Context { get; set; }public AutoMapper.IMapper Mapper { get; set; }public IStockService _stockService { get; set; }/// <summary>/// 新增预约出库单/// </summary>/// <param name="outmodel"></param>/// <returns></returns>public async Task AddAsync(OutstockDemandBillModel outmodel){if (outmodel.AppointmentDate.Date < DateTime.Now.Date){throw new CustomException("预约日期不能小于当前日期");}if (outmodel.PlanArrivalTime <= System.DateTime.Now){throw new CustomException("计划出库时间应大于当前时间");}//对应业务数据处理var outStockEntity = Mapper.Map<OutstockDemandBillEntity>(outmodel);outStockEntity.Id = Guid.NewGuid().ToString("N");outStockEntity.DemandNo = BillExtend.CreateBillCode(CommonConst.CK);this.Context.Set<OutstockDemandBillEntity>().Add(outStockEntity);//明细数据处理foreach (var item in outmodel.Items){var outStockItemEntity = Mapper.Map<OutstockDemandBillItemEntity>(item);outStockItemEntity.Id = Guid.NewGuid().ToString("N");outStockItemEntity.OutstockDemandBillId = outStockEntity.Id;Context.Set<OutstockDemandBillItemEntity>().Add(outStockItemEntity);}//事物操作var tran = Context.Database.BeginTransaction();try{await Context.SaveChangesAsync();tran.Commit();}catch (Exception ex){tran.Rollback();throw new CustomException(ex.Message);}}/// <summary>/// 删除预约出库单/// </summary>/// <param name="outOrderIds">预约出库单Id集合</param>/// <param name="userId">操作人</param>/// <returns></returns>public async Task DeleteAsync(IEnumerable<string> outOrderIds, string userId){if (outOrderIds.Count() == 0){throw new CustomException("请传入有效的出库单Id");}var outStockEntitys = this.Context.Set<OutstockDemandBillEntity>().Where(x => x.IsDelete == DeleteStatus.Normal && outOrderIds.Contains(x.Id)).ToList();if (outStockEntitys.Count() == 0){throw new CustomException("未找到可删除的记录,请检查参数是否传递正确。");}var noDeleteItems = outStockEntitys.Where(x => x.OutStatus != OutOderStatus.TodoAllot);if (noDeleteItems.Count() > 0){throw new CustomException($" { string.Join(",", noDeleteItems.Select(x => x.DemandNo))}当前状态不可删除");}await Context.SaveChangesAsync();foreach (var item in outStockEntitys){item.IsDelete = Core.EnumDefinitions.DeleteStatus.HasDelete;item.Updator = userId;item.UpdateDate = DateTime.Now;await this.UpdateAsync(item);}}/// <summary>/// 编辑预约出库单/// </summary>/// <param name="outmodel">操作对象</param>/// <param name="oprerType">操作类型(0编辑预约单 1预约单任务分配,2预约出库单下架)</param>/// <returns></returns>public async Task EditAsync(OutstockDemandBillModel outmodel, OutOrderOperType operatorType){var outStockEntitys = this.Context.Set<OutstockDemandBillEntity>().SingleOrDefault(x => x.Id == outmodel.Id && x.IsDelete == DeleteStatus.Normal);if (outStockEntitys == null){throw new CustomException("请传入有效的出库单Id");}if (outmodel.AppointmentDate.Date > outmodel.PlanArrivalTime){throw new CustomException("预约时间不能大于计划出库时间!");}Func<string, string> func = goodsId =>{return this.Context.Set<GoodsEntity>().FirstOrDefault(x => x.IsDelete == DeleteStatus.Normal && x.Id == goodsId)?.GoodsName;};switch (operatorType){case OutOrderOperType.EditOrder:if (outStockEntitys.OutStatus != OutOderStatus.TodoAllot){throw new CustomException($"当前状态为【{outStockEntitys.OutStatus.GetDescription()}】不可编辑。");}var outstockItems = this.Context.Set<OutstockDemandBillItemEntity>().Where(x => x.OutstockDemandBillId == outmodel.Id).ToList();this.Context.RemoveRange(outstockItems);//outStockEntitys = Mapper.Map<OutstockDemandBillEntity>(outmodel);outStockEntitys.From(outmodel);var upOutStoclItemEntity = Mapper.Map<List<OutstockDemandBillItemEntity>>(outmodel.Items);upOutStoclItemEntity.ForEach(x =>{x.Id = Guid.NewGuid().ToString("N");x.OutstockDemandBillId = outmodel.Id;x.ActualOutQuantity = x.PlanOutQuantity;x.ActualProductBatch = x.PlanProductBatch;});//this.Context.Set<OutstockDemandBillEntity>().Local.Clear();//this.Context.Set<OutstockDemandBillEntity>().Local.Add(outStockEntitys);//this.Context.Entry(outStockEntitys).State = EntityState.Modified;this.Context.UpdateRange(outStockEntitys);await this.Context.AddRangeAsync(upOutStoclItemEntity);break;case OutOrderOperType.AllotOrder:if (outStockEntitys.OutStatus != OutOderStatus.TodoAllot){throw new CustomException($"当前所传状态为【{outStockEntitys.OutStatus.GetDescription()}】不可进行任务分配操作。");}if (string.IsNullOrWhiteSpace(outmodel.OutstockGroup)){throw new CustomException("出库组不能为空!");}outmodel.Items.ForEach(x =>{if (string.IsNullOrWhiteSpace(x.PlanProductBatch)){throw new CustomException($"【{func(x.GoodsId)}】计划出库批号不能为空");}if (x.ActualOutQuantity <= 0){throw new CustomException($"【{func(x.GoodsId)}-{x.PlanProductBatch}】实际出库数量需大于0");}});outStockEntitys.OutstockGroup = outmodel.OutstockGroup;outStockEntitys.OutStatus = OutOderStatus.DoneAllot;outStockEntitys.TaskTime = System.DateTime.Now;outStockEntitys.TaskUser = outmodel.Updator;outStockEntitys.UpdateDate = System.DateTime.Now;outStockEntitys.Updator = outmodel.Updator;this.Context.Set<OutstockDemandBillEntity>().Update(outStockEntitys);var upOutStockItemEntity = this.Context.Set<OutstockDemandBillItemEntity>().Where(x => x.OutstockDemandBillId == outmodel.Id).ToList();upOutStockItemEntity.ForEach(x =>{x.PlanProductBatch = outmodel.Items.SingleOrDefault(y => y.Id == x.Id).PlanProductBatch;x.ActualOutQuantity = outmodel.Items.SingleOrDefault(y => y.Id == x.Id).ActualOutQuantity;x.ActualProductBatch = outmodel.Items.SingleOrDefault(y => y.Id == x.Id).ActualProductBatch;if (string.IsNullOrWhiteSpace(x.ActualProductBatch)){x.ActualProductBatch = x.PlanProductBatch;}x.UpdateDate = System.DateTime.Now;x.Updator = outmodel.Updator;});this.Context.Set<OutstockDemandBillItemEntity>().UpdateRange(upOutStockItemEntity);break;case OutOrderOperType.OutOder:if (!(outStockEntitys.OutStatus == OutOderStatus.DoneAllot || outStockEntitys.OutStatus == OutOderStatus.OutBoundIng)){throw new CustomException($"当前所传状态为【{outStockEntitys.OutStatus.GetDescription()}】不可进行出库下架操作。");}//待下架完整单据的货物var outStockItems = this.Context.Set<OutstockDemandBillItemEntity>().Where(x => x.OutstockDemandBillId == outmodel.Id).ToList();if (outStockItems.Where(x => x.OffshelvesStatus == OutOderItemStatus.TodoOffshelves).Count() == 0){throw new CustomException("所有货物已全部下架,请勿重复操作!");}//待出库的货物明细var todoOutitems = outmodel.Items.Where(x => !string.IsNullOrWhiteSpace(x.OutstockLocation)&& !string.IsNullOrWhiteSpace(x.ActualProductBatch) && x.ActualOutQuantity > 0).ToList();if (todoOutitems.Count() == 0){throw new CustomException("库位,实际出库批号,不能为空,且实际出库数量必须大于0");}todoOutitems = todoOutitems.Where(x => x.OffshelvesStatus == OutOderItemStatus.TodoOffshelves).ToList();if (todoOutitems.Count() == 0){throw new CustomException("所有货物已全部下架,请勿重复操作!");}//部分下架中存在部分重复出库情况验证处理var offshelveseds = outStockItems.Where(x => x.OffshelvesStatus == OutOderItemStatus.DoneOffshelves);if (offshelveseds.Count() > 0){Func<string, string> funLocation = locationId => this.Context.Set<WareHouseLocationEntity>().SingleOrDefault(x => x.Id == locationId)?.LocationCode;var reportDatas = offshelveseds.Where(y => todoOutitems.Select(x => x.Id).Contains(y.Id)).ToList();if (reportDatas.Count() > 0){var msg = string.Empty;reportDatas.ForEach(x =>{msg +=$"{func(x.GoodsId)};批号:{ x.ActualProductBatch};库位:{funLocation(x.OutstockLocation)}," ;});throw new CustomException($"【{msg.TrimEnd(',')}】已经下架,请勿重复操作!");}}//本次需要下架完整单据的货物var upOutItems = outStockItems.Where(x => todoOutitems.Select(y => y.Id).Contains(x.Id)).ToList();//判断本次操作是否整单全部下架if (outStockItems.Where(x => x.OffshelvesStatus == OutOderItemStatus.DoneOffshelves).Count() + todoOutitems.Count() == outStockItems.Count()){outStockEntitys.OutStatus = OutOderStatus.DoneOutBound;}else{outStockEntitys.OutStatus = OutOderStatus.OutBoundIng;}outStockEntitys.UpdateDate = System.DateTime.Now;outStockEntitys.Updator = outmodel.Updator;this.Context.Update(outStockEntitys);//修改出库明细下架信息upOutItems.ForEach(x =>{x.ActualOutQuantity= todoOutitems.FirstOrDefault(y => y.Id == x.Id).ActualOutQuantity;x.ActualProductBatch = todoOutitems.FirstOrDefault(y => y.Id == x.Id)?.ActualProductBatch;x.OutstockLocation = todoOutitems.FirstOrDefault(y => y.Id == x.Id)?.OutstockLocation;x.OffshelvesStatus = OutOderItemStatus.DoneOffshelves;x.Offshelves = outmodel.Updator;x.OffshelvesTime = DateTime.Now;});this.Context.UpdateRange(upOutItems);#region 调库存接口 var todoMapOutStock = Mapper.Map<List<StockModel>>(upOutItems);var todoAddStock= todoMapOutStock.Select(x =>{x.Id = string.Empty; x.BillNo = outmodel.DemandNo; x.AreaId = outmodel.AreaId;x.CreateDate = System.DateTime.Now; x.Creator = outmodel.Creator; x.UpdateDate = System.DateTime.Now; x.Updator = outmodel.Updator; return x;}).ToList();await _stockService.AddStock(todoAddStock, this.Context, false);#endregionbreak;}var tran = Context.Database.BeginTransaction();try{//提交事务操作数据await Context.SaveChangesAsync();tran.Commit();}catch (Exception ex){tran.Rollback();throw new CustomException(ex.Message);}}/// <summary>/// /// <summary>/// 条件获取出库单信息/// </summary>/// <param name="key">出库单号,主键Id,需求商Id</param>/// <param name="areaId">库区编号</param>/// <param name="outStatus">出库单状态</param>/// <param name="startTime">预约开始时间</param>/// <param name="endTime">预约结束时间</param>/// <param name="pageIndex">页码</param>/// <param name="pageSize">每页显示的值</param>/// <returns></returns>/// </summary>public async Task<Page<OutstockDemandBillListModel>> GetPageList(string key, string areaId, int outStatus, DateTime? startTime, DateTime? endTime, int pageIndex, int pageSize){Expression<Func<OutstockDemandBillEntity, bool>> where = m => m.IsDelete == DeleteStatus.Normal;if (!string.IsNullOrWhiteSpace(key)){where = where.And(x => x.Id == key || x.DemanderId == key || x.DemandNo.Contains(key));}if (!string.IsNullOrWhiteSpace(areaId)){where = where.And(x => x.AreaId == areaId);}if (outStatus >= 0){where = where.And(x => x.OutStatus == (OutOderStatus)outStatus);}if (startTime != null && endTime != null && startTime != DateTime.MinValue && endTime != DateTime.MinValue){if (Convert.ToDateTime(startTime).Date > Convert.ToDateTime(endTime).Date){throw new CustomException("开始时间不能大于结束时间");}}if (startTime != null && startTime != DateTime.MinValue){where = where.And(x => x.AppointmentDate > Convert.ToDateTime(startTime).Date);}if (endTime != null && endTime != DateTime.MinValue){where = where.And(x => x.AppointmentDate < Convert.ToDateTime(endTime).AddDays(1).Date);}var query = this.Context.Set<OutstockDemandBillEntity>().Where(where);pageIndex = pageIndex <= 0 ? 1 : pageIndex;pageSize = pageSize <= 0 ? 10 : pageSize;var amount = await query.CountAsync();var totlePage = (amount - 1) / pageSize + 1;if (pageIndex > totlePage){pageIndex = totlePage;}query = query.Skip((pageIndex - 1) * pageSize).Take(pageSize);List<OutstockDemandBillListModel> rlist = new List<OutstockDemandBillListModel>();if (query.Count() > 0){rlist = Mapper.Map<List<OutstockDemandBillListModel>>(query.ToList());if (rlist.Count() > 0){var areaInfos = this.Context.Set<WareHouseAreaEntity>().Where(x => rlist.Select(y => y.AreaId).Contains(x.Id)).ToList();var demanInfos = this.Context.Set<DemanderEntity>().Where(x => rlist.Select(y => y.DemanderId).Contains(x.Id)).ToList();foreach (var item in rlist){item.AreaName = areaInfos.FirstOrDefault(x => x.Id == item.AreaId)?.AreaName;item.DemanderName = demanInfos.FirstOrDefault(x => x.Id == item.DemanderId)?.DemanderName;}}}var page = new Page<OutstockDemandBillListModel>() { Size = pageSize, Index = pageIndex, Amount = amount, Datas = rlist };return page;}/// <summary>/// 获取出库单明细/// </summary>/// <param name="key">关键字</param>/// <returns></returns>public OutstockDemandBillModel GetOutStockItemList(string key){OutstockDemandBillModel rmodel = new OutstockDemandBillModel();Func<string, string> funcArea = areaId =>{return this.Context.Set<WareHouseAreaEntity>().FirstOrDefault(x => x.Id.Equals(areaId))?.AreaName;};Func<string, string> funcDeman = demanId =>{return this.Context.Set<DemanderEntity>().FirstOrDefault(x => x.Id.Equals(demanId))?.DemanderName;};if (string.IsNullOrWhiteSpace(key)){throw new CustomException("传入参数不能为空!");}var rOderEntity = this.Context.Set<OutstockDemandBillEntity>().FirstOrDefault(x => x.Id == key && x.IsDelete == DeleteStatus.Normal);if (rOderEntity == null){throw new CustomException("未找到对应的出库单,请传入有效的查询参数!");}rmodel = Mapper.Map<OutstockDemandBillModel>(rOderEntity);rmodel.AreaName = funcArea(rmodel.AreaId);rmodel.DemanderName = funcDeman(rmodel.DemanderId);var rOrderItems = this.Context.Set<OutstockDemandBillItemEntity>().Where(x => x.OutstockDemandBillId == key).ToList();if (rOrderItems.Count() > 0){rmodel.Items = Mapper.Map<List<OutstockDemandBillItemModel>>(rOrderItems);}return rmodel;}}
}

.net Core增删改查(API)相关推荐

  1. ASP.Net Core 增删改查列表实例(三)

    一..Net Core Minimai API 1.体积小,无需Api Controller 2.易编写,极简编程体验 3.简洁性,program搞定所有 创建完Web API后,打开Program. ...

  2. ES的索引库(数据表)基础操作 —— 增删改查API版

    索引库操作 索引库就类似数据库表,mapping映射就类似表的结构,对索引库的操作就类似于对数据库表的操作(为便于理解,以下描述有一些是用数据库表来描述的). 我们要向es中存储数据,必须先创建&qu ...

  3. 【我的开源】拿来即用!代码生成器:mybatis-plus-generator自定义模板生成 DTO、VO、Convertor、增删改查方法

    mybatis-plus 官网: https://baomidou.com/ 官网上面的资料很全,本文以: <mybatis-plus-generator.version>3.5.1< ...

  4. 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查

    基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查 转载于:https://github.com/Meowv/Blog 本篇说一下自定义仓储的实现方式,其实在ab ...

  5. 国产化之路-统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作

    引言 经过前期的准备工作,.net core 3.1的运行环境和WEB服务器已经搭建完毕,这里需要注意一下,达梦DM8数据库对于Entity Framework Core 3.1 的驱动在NuGet官 ...

  6. mysql sqlsugar_.net core +mysqlSugar(最为简单的增删改查)

    首先建立.net Core API - empty 这个就不说了 然后创建新的Controller 记得添加路由 [Route("api/Users")] 然后在Nuget Pac ...

  7. 前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查

    首页 > 技术 > 编程 > NET > 前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查 前端使用AngularJS的$res ...

  8. javaweb简单的登录增删改查系统_国产化之路统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作...

    引言 经过前期的准备工作,.net core 3.1的运行环境和WEB服务器已经搭建完毕,这里需要注意一下,达梦DM8数据库对于Entity Framework Core 3.1 的驱动在NuGet官 ...

  9. Elasticsearch Javascript API增删改查

    查询 根据索引.类型.id进行查询: client.get({ index:'myindex', type:'mytype', id:1 },function(error, response){// ...

最新文章

  1. fan怎么写 jin_fanjin怎么写
  2. httpclient 调取接口_使用HttpClient调用接口的实例讲解
  3. 干货 | 旷视科技俞刚:我在旷视研究院做检测
  4. 现代制造工程——考试复习01
  5. 计算机的硬件性能指标(图片部分资源摘自王道考研资料)
  6. 计算机卡在无法显示网页,我的电脑上网上银行一直“无法显示网页”
  7. idea全局搜索快捷鍵ctrl+shift+F失效
  8. 今天你多态了吗? 【转】
  9. 【codevs1368】【BZOJ1034】泡泡堂BNB,贪心思路
  10. 2017.10.9 DZY Loves Math V 失败总结
  11. Java 1.1字符串
  12. elastix中NAT穿越问题解决办法
  13. 汪文君 java_汪文君JAVA多线程编程实战 视频教程 下载
  14. 最简单的dubbo教程-快速入门
  15. Flask 使用abort方法返回http错误码、http错误响应信息
  16. HDMI2.0/HDCP2.2 2x4 矩阵芯片——GSV2006
  17. Led台灯对眼睛好吗?2022双十一不伤眼的护眼灯推荐
  18. 基础30讲 第六讲 中值定理
  19. 信号完整性之眼图(eye)理解(二)
  20. 数据结构之广义表(C语言)

热门文章

  1. 计算机怎么设置用户权限,详细教你怎么设置win7管理员权限
  2. solr group分组查询
  3. 服务器监控系统哪家性价比高,4G内存的服务器怎么样?性价比高吗?集光安防的这一款怎么样?...
  4. c50弹性模量计算_C50混凝土配合比设计计算书
  5. 第4章第2节:如何往幻灯片中使用Excel电子表格 [PowerPoint精美幻灯片实战教程]
  6. 测试文章样式2222222222
  7. 抖音小店无货源玩法分享(一)开店前准备,核心思路奉上
  8. 一堆被称之为大学的东西——思想和精神
  9. 如何在vr中进行视频播放
  10. python爬取托福_Python 统计托福作文词频