Here is my code; as you can see, I am saving changes for each row, but I want to make performance faster because I have large amount of data every time, like 50.000 or 100.000 rows or more. This takes a lot of time to finish.
How can I improve my EF SaveChanges performance? I tried bulksave, bulkupdate with some third party library, but it is not updating in the database. This takes 2 hours to update 50.000 rows. I want to improve time for this method.
private void TransferOrders()
{
    using (var context = new BbsfDbContext())
    {
        context.DisableFilter(AbpDataFilters.MayHaveTenant);
        context.DisableFilter("LanguageSpecificFilter");
        var sapOrders = context.SapOrders
                               .Where(p => p.VBTYP != null && 
                                           p.VBTYP.ToLower() == OrderDocumentType && 
                                           p.IsRead == false)
                                //.Where(p => p.VBTYP != null && p.VBTYP.ToLower() == OrderDocumentType && p.Id == 3025)
                               .Where(p => !ActiveUsersOnly || context.Users.Where(u => u.IsActive).Select(a => a.MainVendor.SapCode).Contains(p.KUNNR))
                               .OrderBy(p => p.CreatedDate)
                               .ToList();
        if (sapOrders.Any())
        {
            foreach (var item in sapOrders)
            {
                try
                {
                    var order = context.Orders.FirstOrDefault(p => p.SapCode == item.VBELN);
                    var isExist = context.SapOrderDetails.Any(p => p.DOCNUM == item.DOCNUM);
                    if (isExist)
                    {
                        var salesOrganization = context.SalesOrganizations.FirstOrDefault(p => p.SapCode == item.VKORG);
                        if (salesOrganization == null)
                            continue;
                        var distributionChannel = context.DistributionChannels.FirstOrDefault(p => p.SapCode == item.VTWEG);
                        if (distributionChannel == null)
                            continue;
                        var salesDepartment = context.SalesDepartments.FirstOrDefault(p => p.SapCode == item.SPART);
                        if (salesDepartment == null)
                            continue;
                        var salesOffice = context.SalesOffices
                                                 .FirstOrDefault(p => p.SapCode == item.VKBUR &&
                                                     p.SalesOrganization.Id == salesOrganization.Id &&
                                                     p.DistributionChannel.Id == distributionChannel.Id &&
                                                     p.SalesDepartment.Id == salesDepartment.Id);
                        if (salesOffice == null)
                            continue;
                        var ordererCustomer = context.Customers
                                .FirstOrDefault(p => p.SapCode == item.KUNNR &&
                                                     p.SalesOrganization.Id == salesOrganization.Id &&
                                                     p.DistributionChannel.Id == distributionChannel.Id &&
                                                     p.SalesDepartment.Id == salesDepartment.Id &&
                                                     p.SalesOffice.Id == salesOffice.Id);
                        var recipientCustomer = context.Customers
                                .FirstOrDefault(p => p.SapCode == item.KUNWE &&
                                                     p.SalesOrganization.Id == salesOrganization.Id &&
                                                     p.DistributionChannel.Id == distributionChannel.Id &&
                                                     p.SalesDepartment.Id == salesDepartment.Id &&
                                                     p.SalesOffice.Id == salesOffice.Id);
                        if (recipientCustomer == null)
                            recipientCustomer = context.Customers
                                    .FirstOrDefault(p => p.SapCode == item.KUNWE &&
                                                         p.SalesOrganization.Id == salesOrganization.Id &&
                                                         p.DistributionChannel.Id == distributionChannel.Id &&
                                                         p.SalesDepartment.Id == salesDepartment.Id &&
                                                         p.SalesOffice == null);
                        if (ordererCustomer == null || recipientCustomer == null)
                            continue;
                        if (order == null)
                        {
                            order = new Order
                                {
                                    SapCode = item.VBELN,
                                    SapOrderDate = item.AUDAT,
                                    DocumentType = context.DocumentTypes.FirstOrDefault(p => p.SapCode == item.VBTYP),
                                    SalesDocument = context.SalesDocuments.FirstOrDefault(p => p.SapCode == item.AUART),
                                    BaseAmount = item.NETWR,
                                    TotalTax = item.MWSBT,
                                    Currency = context.CurrencyDefinitions.FirstOrDefault(p => p.SapCode == item.WAERK),
                                    SalesOrganization = salesOrganization,
                                    DistributionChannel = distributionChannel,
                                    SalesDepartment = salesDepartment,
                                    SalesGroup = context.SalesGroups.FirstOrDefault(p => p.SapCode == item.VKGRP && p.SalesOffice.Id == salesOffice.Id),
                                    SalesOffice = salesOffice,
                                    RequestedDeliveryDate = item.VDATU,
                                    SASNo = item.BSTNK,
                                    SASOrderDate = item.BSTDK ?? item.AUDAT,
                                    OrdererCustomer = ordererCustomer,
                                    RecipientCustomer = recipientCustomer,
                                    //PRSDT
                                    Status = OrderStatus.Approved,
                                    Type = OrderType.MainVendor,
                                    DeliveryAddress = context.CustomerAddressBooks.FirstOrDefault(p => p.MainVendor.Id == ordererCustomer.Id && p.SubVendor.Id == recipientCustomer.Id),
                                    CreationTime = DateTime.Now,
                                    LastModificationTime = DateTime.Now,
                                    CreatorUserId = context.Users.First(p => p.UserName == AbpUserBase.AdminUserName).Id,
                                    LastModifierUserId = context.Users.First(p => p.UserName == AbpUserBase.AdminUserName).Id,
                                    IsSubVendorOrder = false,
                                    IsSameDayDelivery = false,
                                    RepresentativeId = context.Users.First(p => p.UserName == AbpUserBase.AdminUserName).Id
                                    //ProductionSite
                                    //RejectionReason =//todo:bu silinmeli iptal kalem bazında burada statu olmalı
                                };
                                var savedOrder = context.Orders.Add(order);
                                context.SaveChanges();
                                order.SASNo = BbsfConsts.KeasOrderNumberPrefix + savedOrder.Id;
                            }
                            else
                            {
                                order.SapOrderDate = item.AUDAT;
                                order.DocumentType = context.DocumentTypes.FirstOrDefault(p => p.SapCode == item.VBTYP);
                                order.SalesDocument = context.SalesDocuments.FirstOrDefault(p => p.SapCode == item.AUART);
                                order.BaseAmount = item.NETWR;
                                order.TotalTax = item.MWSBT;
                                order.Currency = context.CurrencyDefinitions.FirstOrDefault(p => p.SapCode == item.WAERK);
                                order.SalesOrganization = salesOrganization;
                                order.DistributionChannel = distributionChannel;
                                order.SalesDepartment = salesDepartment;
                                order.SalesGroup = context.SalesGroups.FirstOrDefault(p => p.SapCode == item.VKGRP && p.SalesOffice.Id == salesOffice.Id);
                                order.SalesOffice = salesOffice;
                                order.RequestedDeliveryDate = item.VDATU;
                                order.SASNo = BbsfConsts.KeasOrderNumberPrefix + order.Id;
                                //order.SASOrderDate = item.BSTDK.HasValue ? item.BSTDK : item.AUDAT;
                                order.OrdererCustomer = ordererCustomer;
                                order.RecipientCustomer = recipientCustomer;
                                //PRSDT
                                //order.Status = OrderStatus.Approved;
                                order.DeliveryAddress = context.CustomerAddressBooks.FirstOrDefault(p => p.MainVendor.Id == ordererCustomer.Id && p.SubVendor.Id == recipientCustomer.Id);
                                order.LastModifierUserId = context.Users.First(p => p.UserName == AbpUserBase.AdminUserName).Id;
                                order.LastModificationTime = DateTime.Now;
                                //ProductionSite
                                //RejectionReason =//todo:bu silinmeli iptal kalem bazında burada statu olmalı
                            }
                        }
                        else
                        {
                            if (order != null)
                            {
                                var orderDetails = context.OrderDetails.Where(p => p.OrderId == order.Id).ToList();
                                orderDetails?.ForEach(p => context.OrderDetails.Remove(p));
                                context.SaveChanges();
                                context.Orders.Remove(order);
                                context.SaveChanges();
                            }
                        }
                        item.IsRead = true;
                        item.ModifiedDate = DateTime.Now;
                        context.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, MethodBase.GetCurrentMethod().Name + " Error During IDOCOperations " + ex.Message);
                        continue;
                    }
                }
            }
        }
    }
 
     
     
     
    