项目背景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. 交叉验证(cross validation)是什么?K折交叉验证(k-fold crossValidation)是什么?
  2. 机器学习和计算机视觉有关的数学
  3. 计算机应用基础任务化教程知识点,计算机应用基础任务化教程
  4. springboot 获取application参数_LOOK ! SpringBoot的外部化配置最全解析
  5. hpunix下11gRac的安装
  6. oracle 容器运行_Oracle应用容器云的自由
  7. Python为你打开一扇门
  8. Python 内置函数介绍
  9. Vue路由如何设置导航选中(高亮)
  10. 用字符串模拟两个大数的相加
  11. 计算机维修技师论文,2016年电工技师论文范文10篇
  12. 外汇套利原理及策略EA
  13. 昨天晚上看了冰川时代三
  14. 机器学习算法各个击破
  15. 【CodeForces - 869】 A B C E 【组合数打表】
  16. AI数学基础(2)--- 霍夫丁不等式
  17. 拉斯维加斯国际黑客大会 本周开战
  18. 华为云FusionInsight MRS容灾:大数据两地三中心的容灾也可以如此省心
  19. LabVIEW 2013SP1视觉开发必备软件LV、VDM、VBAI、VAS
  20. 移动硬盘弹出时总是显示被占用,解决方案

热门文章

  1. python 数据库编程,这篇是针对 mysql 的,滚雪球学Python第4季第13篇
  2. Tomcat 禁用管理界面
  3. essentialpim mysql,EssentialPIM
  4. 芯梦启航五种流水灯模式
  5. Nginx下配置codeigniter框架方法
  6. 新浪博客的视频如何下载
  7. 做好领导者和管理者的10条法则
  8. 24页狼性文化PPT,教你如何培养狼性文化
  9. html中 hr 的几种不同的语句及效果
  10. win10 安装 ros2.0---ROS Bouncy