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;
}
}
}
}
}