У меня есть метод, у него большой список размеров и ведение бизнеса для каждого элемента. И это занимает слишком много времени. Поэтому я хочу разделить этот список на меньший список. Например, если у меня 100 000 элементов, я делю этот список на 100 подсписков, каждый из которых содержит 1000 элементов, и я хочу вызвать мой метод один раз, но это должно происходить 100 раз вовремя, я думаю, для этого мне нужны потоки. Есть ли решение по моему запросу? Спасибо. Вот мой код:
private void TransferOrderDetails()
{
using (var context = new BbsfDbContext())
{
context.DisableFilter(AbpDataFilters.MayHaveTenant);
context.DisableFilter("LanguageSpecificFilter");
List<SapOrderDetail> sapOrderDetails = new List<SapOrderDetail>();
List<OrderDetailView> orderDetails = new List<OrderDetailView>();
using (new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
{
//In here I have 100.000 or above records it takes 2 hours finish this method
sapOrderDetails = context.SapOrderDetails
.Where(p => p.IsRead == false)
.Where(p => !context.Orders.Select(a => a.Quote.SapCode).Contains(p.VBELN))
.Where(p => context.Orders.Any(o => o.SapCode == p.VBELN)
&& context.ProductionSites.Any(a => a.SapCode == p.WERKS))
.OrderBy(p => p.CreatedDate)
.ToList();
//orderDetails = context.OrderDetailView.ToList();
}
//ListExtensions.ChunkBy(sapOrderDetails, 1000);
if (!sapOrderDetails.Any()) return;
var productionSites = context.ProductionSites.AsNoTracking().ToList();
var productGroups = context.ProductGroups.Include(a => a.ParentGroup).Select(p => new { p.Id, p.ParentGroup }).AsNoTracking().ToList();
var contractDetails = context.ContractDetails.AsNoTracking().ToList();
var materialGroups = context.MaterialGroups.AsNoTracking().ToList();
var rejectionReasons = context.RejectionReasons.AsNoTracking().ToList();
var currencyDefinitions = context.CurrencyDefinitions.AsNoTracking().ToList();
var measurementUnits = context.MeasurementUnits.AsNoTracking().ToList();
var salesDepots = context.SalesDepots.AsNoTracking().ToList();
var shipmentPoints = context.ShipmentPoints.AsNoTracking().ToList();
var stockStatusTypes = context.StockStatusTypes.ToList();
var user = context.Users.FirstOrDefault(u => u.UserName == AbpUserBase.AdminUserName);
var counter = 0;
foreach (var item in sapOrderDetails)
{
counter++;
try
{
Order order = null;
OrderDetail orderDetail = null;
var detail = context.OrderDetails
.Include(a => a.Order)
.FirstOrDefault(a => a.Order.SapCode == item.VBELN && a.SapCode == item.POSNR);
if (detail != null)
{
order = detail.Order;
orderDetail = detail;
}
if (order == null)
{
order = context.Orders.FirstOrDefault(p => p.SapCode == item.VBELN);
if (order == null)
continue;
}
var productionSite = context.ProductionSites.FirstOrDefault(p => p.SapCode == item.WERKS);
if (productionSite == null)
continue;
var product = context.Products.Include("ProductGroup").FirstOrDefault(p => p.SapCode == item.MATNR && p.ProductionSite.Id == productionSite.Id);
if (product == null)
continue;
var stockStatus = stockStatusTypes.FirstOrDefault(s => s.Id == product.GeneralStockStatusId);
var contractDetail = contractDetails.FirstOrDefault(p => p.ContractSapCode == item.VGBEL && p.SapCode == item.VGPOS);
if (orderDetail == null)
{
orderDetail = context.OrderDetails.FirstOrDefault(p => p.OrderId == order.Id && p.SapCode == item.POSNR);
}
if (product.ProductGroup != null)
{
var productGroup3 = context.ProductGroups.Include("ParentGroup").FirstOrDefault(p => p.Id == product.ProductGroup.Id);
if (productGroup3 != null && productGroup3.ParentGroup != null)
{
var productGroup2 = context.ProductGroups.Include("ParentGroup").FirstOrDefault(p => p.Id == productGroup3.ParentGroup.Id);
if (productGroup2 != null && productGroup2.ParentGroup != null)
{
var productGroup1 = context.ProductGroups.Include("ParentGroup").FirstOrDefault(p => p.Id == productGroup2.ParentGroup.Id);
if (productGroup1 != null && productGroup1.ParentGroup != null)
order.ProductGroup = productGroup1.ParentGroup;
}
}
}
if (orderDetail == null)
{
orderDetail = new OrderDetail
{
Order = order,
SapCode = item.POSNR,
Product = product,
MaterialGroup = materialGroups.FirstOrDefault(p => p.SapCode == item.MATKL),
RejectionReason = rejectionReasons.FirstOrDefault(p => p.SapCode == item.ABGRU),
BaseAmount = item.NETWR,
Currency = currencyDefinitions.FirstOrDefault(p => p.SapCode == item.WAERK),
OrderAmount = item.KWMENG,
MeasurementUnit = measurementUnits.FirstOrDefault(p => p.IsoCode == item.VRKME),
GrossWeight = item.BRGEW,
NetWeight = item.NTGEW,
WeightUnit = measurementUnits.FirstOrDefault(p => p.IsoCode == item.GEWEI),
ContractSapCode = item.VGBEL,
ContractDetailSapCode = item.VGPOS,
ContractName = contractDetail?.Name,
//ProductionSite = productionSite,
SalesDepot = salesDepots.FirstOrDefault(p => p.SapCode == item.LGORT),
ShipmentPoint = shipmentPoints.FirstOrDefault(p => p.SapCode == item.VSTEL),
NetPrice = item.NETPR,
//PEINH
//PMENE
//VGTYP
Tax = item.MWSBP,
//PRSDT
RequestedAmount = item.KWMENG,
RequestedDeliveryDate = item.ZZMITT,
CreationTime = DateTime.Now,
LastModificationTime = DateTime.Now,
CreatorUserId = user.Id,
LastModifierUserId = user.Id,
IsDueDateRequested = item.ZZPRODDATE.HasValue,
DueDate = (string.IsNullOrEmpty(item.MVGR3) && item.ZZPRODDATE.HasValue) ? DateTime.Now : item.ZZPRODDATE,
DeliveryStatus = item.ZZPRODDATE.HasValue ? OrderDetailDeliveryStatus.FulfilledDueDate : OrderDetailDeliveryStatus.Approved,
StockStatus = stockStatus,
Note = item.MusteriNotu,
Uepos = item.UEPOS,
Type = item.PSTYV,
DOCNUM = item.DOCNUM,
ProductParty = item.CHARG
};
orderDetail.ProductionSiteId = productionSite?.Id;
if (orderDetail.RejectionReason != null || orderDetail.RejectionReasonId != null)
{
orderDetail.Status = OrderDetailStatus.Canceled;
orderDetail.DeliveryStatus = OrderDetailDeliveryStatus.Canceled;
}
if (string.IsNullOrEmpty(item.MVGR3) && item.ZZPRODDATE.HasValue)
orderDetail.DueDate = DateTime.Now;
else
orderDetail.DueDate = item.ZZPRODDATE;
context.OrderDetails.Add(orderDetail);
}
else
{
orderDetail.Product = product;
orderDetail.MaterialGroup = materialGroups.FirstOrDefault(p => p.SapCode == item.MATKL);
orderDetail.RejectionReason = rejectionReasons.FirstOrDefault(p => p.SapCode == item.ABGRU);
orderDetail.BaseAmount = item.NETWR;
orderDetail.Currency = currencyDefinitions.FirstOrDefault(p => p.SapCode == item.WAERK);
orderDetail.OrderAmount = item.KWMENG;
orderDetail.MeasurementUnit = measurementUnits.FirstOrDefault(p => p.IsoCode == item.VRKME);
orderDetail.GrossWeight = item.BRGEW;
orderDetail.NetWeight = item.NTGEW;
orderDetail.WeightUnit = measurementUnits.FirstOrDefault(p => p.IsoCode == item.GEWEI);
orderDetail.ContractSapCode = item.VGBEL;
orderDetail.ContractDetailSapCode = item.VGPOS;
//orderDetail.ProductionSite = productionSite;
orderDetail.SalesDepot = salesDepots.FirstOrDefault(p => p.SapCode == item.LGORT);
orderDetail.ShipmentPoint = shipmentPoints.FirstOrDefault(p => p.SapCode == item.VSTEL);
orderDetail.NetPrice = item.NETPR;
//PEINH
//PMENE
//VGTYP
orderDetail.Tax = item.MWSBP;
//PRSDT
//orderDetail.RequestedAmount = orderDetail.RequestedAmount.HasValue ? orderDetail.RequestedAmount : item.KWMENG;
orderDetail.RequestedDeliveryDate = orderDetail.RequestedDeliveryDate.HasValue ? orderDetail.RequestedDeliveryDate : item.ZZMITT;
orderDetail.LastModifierUserId = user.Id;
orderDetail.LastModificationTime = DateTime.Now;
orderDetail.DueDate = (string.IsNullOrEmpty(item.MVGR3) && item.ZZPRODDATE.HasValue) ? DateTime.Now : item.ZZPRODDATE;
//orderDetail.IsDueDateRequested = item.ZZPRODDATE.HasValue;
orderDetail.Note = item.MusteriNotu;
orderDetail.Uepos = item.UEPOS;
orderDetail.Type = item.PSTYV;
orderDetail.DOCNUM = item.DOCNUM;
orderDetail.ProductParty = item.CHARG;
if (contractDetail != null && !string.IsNullOrEmpty(contractDetail.Name))
orderDetail.ContractName = contractDetail.Name;
//todo delivery statusleri sil
//termın ıstenmısse statusu termın verıldı olmalı
if (!orderDetail.DeliveryStatus.HasValue && orderDetail.IsDueDateRequested)
orderDetail.DeliveryStatus = OrderDetailDeliveryStatus.AwaitingDueDate;
//durumu termin bekliyor olan kaleme termin verildiğinde statusu termın verıldı olmalı
if ((!orderDetail.DeliveryStatus.HasValue || orderDetail.DeliveryStatus == OrderDetailDeliveryStatus.AwaitingDueDate) && orderDetail.DueDate.HasValue)
orderDetail.DeliveryStatus = OrderDetailDeliveryStatus.FulfilledDueDate;
orderDetail.ProductionSiteId = productionSite?.Id;
if ((orderDetail.RejectionReason != null || orderDetail.RejectionReasonId != null) && item.ABGRU != null)
{
orderDetail.Status = OrderDetailStatus.Canceled;
}
if (item.ABGRU == null)
{
orderDetail.Status = OrderDetailStatus.Open;
orderDetail.RejectionReasonId = null;
if (!orderDetail.DeliveryStatus.HasValue && orderDetail.IsDueDateRequested)
orderDetail.DeliveryStatus = OrderDetailDeliveryStatus.AwaitingDueDate;
else if ((!orderDetail.DeliveryStatus.HasValue || orderDetail.DeliveryStatus == OrderDetailDeliveryStatus.AwaitingDueDate) && orderDetail.DueDate.HasValue)
orderDetail.DeliveryStatus = OrderDetailDeliveryStatus.FulfilledDueDate;
else
orderDetail.DeliveryStatus = OrderDetailDeliveryStatus.Canceled;
}
if (string.IsNullOrEmpty(item.MVGR3) && item.ZZPRODDATE.HasValue)
orderDetail.DueDate = DateTime.Now;
else
orderDetail.DueDate = item.ZZPRODDATE;
}
item.IsRead = true;
item.ModifiedDate = DateTime.Now;
}
catch (Exception ex)
{
logger.Error(ex, MethodBase.GetCurrentMethod().Name + " Error During IDOCOperations " + ex.Message);
continue;
}
}
try
{
context.BulkSaveChanges(false);
}
catch (Exception ex)
{
logger.Error(ex, MethodBase.GetCurrentMethod().Name + " Error During IDOCOperations " + ex.Message);
}
}
}