首页 > 解决方案 > 如何将大列表划分为较小的列表,例如,每个列表包含 1000 个元素并在新列表计数时调用方法?

问题描述

我有一个方法,它有大尺寸列表并为每个元素做一些业务。而且需要的时间太长。所以我想把这个列表分成更小的列表。例如,如果我有 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);
            }
        }
    }

标签: c#.netlistentity-frameworkgenerics

解决方案


推荐阅读