Parallel foreach issue while deleting a record

Posted by Community Admin on 04-Aug-2018 18:38

Parallel foreach issue while deleting a record

All Replies

Posted by Community Admin on 30-Jul-2014 00:00

Hi,

Please find below code where I am trying to acheive parallel deleting of all products in sitefinity. Looks like there is a scoping issue. 

   using (CatalogManager catMgr = CatalogManager.GetManager())
           
                List<Product> products = catMgr.GetProducts().ToList();

                Parallel.ForEach(products, product =>
                    catMgr.DeleteProduct(product);
                    catMgr.SaveChanges();
                );                 
             

 

This code gives the error <b>Object references between two different object scopes are not allowed. The object 'Telerik.Sitefinity.DynamicTypes.Model.sf_ec_prdct_generalproduct' is already managed by 'ObjectScopeImpl 0x38 OpenAccessRuntime.EnlistableObjectScope' and was tried to be managed again by 'ObjectScopeImpl 0xfd OpenAccessRuntime.EnlistableObjectScope'.</b>

Please let me know in case I am missing something.

Thanks

Praneeth

Posted by Community Admin on 04-Aug-2014 00:00

Hi Praneeth,

The error is caused by the fact that the manager did not save changes between two different operations, thus the managers works in different scope, which is not allowed.

More information about deletion of Products could be found here.

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 04-Aug-2014 00:00

Thank you for your reply. Please let me know in case there is any alternative to parallely delete multiple records. I cannot rely on one by one delete as I have approximately 200,000 records and it is taking a very lot of time.

Thanks
Praneeth

Posted by Community Admin on 06-Aug-2014 00:00

Hello Praneeth,

As the parallel items deletion is not allowed, the option for is to get all the Items (Products) in a batches (for example by 500), iterate in a loop and delete them one by one. Than to call manager.SaveChanges() after each batch.

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 20-Sep-2014 00:00

Anything similar to insert multiple users/products/orders. Please note all are new users/products/orders.

This task is for migrating from existing ecomm database to sitefinity database.

 Thanks,
Praneeth

Posted by Community Admin on 22-Sep-2014 00:00

Hello Praneeth,

More information and samples about eCommerce API is available in that documentation.

How to manage users programatically is described here.

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 03-Dec-2014 00:00

Hello Svetoslav,

 Based on the suggestion I did write the code in batches but it still seem to be slow. I tried batches of 10. Please find my codesnippet below. catalogmanager.SaveChanges() for 10 products takes a long time. Please check and let me know in case I missed anything.

 

 private void DeleteProducts(DynamicModuleManager dynamicModuleManager, DynamicContent content, IEnumerable<ProductImportCSV> products)
   
        try
       
            DynamicContent dynamicItemMaster = dynamicModuleManager.Lifecycle.Edit(content) as DynamicContent;

            if (dynamicItemMaster == null)
           
                throw new ApplicationException("DeleteProducts Product Dynamic Item Master was null!");
           

            DynamicContent dynamicItemTemp = dynamicModuleManager.Lifecycle.CheckOut(dynamicItemMaster) as DynamicContent;

            if (dynamicItemTemp == null)
           
                throw new ApplicationException("DeleteProducts Product Dynamic Item Temp was null!");
           

            dynamicItemTemp.SetValue(BatchUploadConstants.JobStatus, ProductBatchUploadStatus.Deleting.ToString());

            PublishDynamicModule(dynamicModuleManager, dynamicItemTemp);
            Guid vendorid = content.GetValue<Guid>(BatchUploadConstants.VendorId);

            using (CatalogManager catalogManager = CatalogManager.GetManager())
           
                catalogManager.Provider.SuppressSecurityChecks = true;

                IEnumerable<ProductImportCSV> productImportCsvs = products as IList<ProductImportCSV> ?? products.ToList();
                // ignore empty records. most likely issue with csv
                productImportCsvs = productImportCsvs.Where(p => !string.IsNullOrEmpty(p.SKU));
                IQueryable<Product> masterProducts = catalogManager.GetProducts().Where(p => p.Status == ContentLifecycleStatus.Master );

                var deleteMasterProducts = Enumerable.Where(masterProducts, p => p.GetValue<TrackedList<Guid>>(DynamicProductConstants.Category).Contains(vendorid));
 
                  // Run in batches
                int skip = 0;
                int take = _batchSize == 0 ? 10 : _batchSize;
                int currentCount = 0;

                int totalCount = deleteMasterProducts.Count();
                while (currentCount < totalCount)
               
                    string skusNotDeleted = string.Empty;
                    try
                   
                       var chunkedProducts = deleteMasterProducts.Skip(skip).Take(take);
                        skip = skip + take;
                        currentCount = skip;

                        foreach (Product product in chunkedProducts)
                       
                            if (string.IsNullOrEmpty(product.Sku))
                           
                                continue;
                           

                            skusNotDeleted += product.Sku + " ,";
                            catalogManager.DeleteProduct(product);
                           
                       

                        catalogManager.Provider.FlushTransaction();
                        catalogManager.SaveChanges();
                        GC.Collect();
                   
                    catch
                        _errorLog.Append(" SKUs not deleted are : " + skusNotDeleted + ". ");
                   
                                

           
       
        catch (Exception ex)
       
            _errorLog.Append("Error occurred while deleting and exception message is : " + ex.Message + " " + Environment.NewLine);
       
   

Posted by Community Admin on 08-Dec-2014 00:00

Hello Praneeth,

The code seems OK. Furthermore I have test product deletion of 12 products using the following code:

public static void DeleteProducts()
    CatalogManager catalogManager = CatalogManager.GetManager();
 
    var products = catalogManager.GetProducts();
 
    foreach (var product in products)
    
        catalogManager.DeleteItem(product, null);
    
    catalogManager.SaveChanges();

and SaveChanges() takes just few (2-3) seconds. I would recommend you to open a support ticket in order to provide us with your project and to inspect the issue locally.

Regards,
Svetoslav Manchev
Telerik
 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 02-Mar-2016 00:00

To delete the records i have used below code.

I have created the records using the dynamic module and wanted to delete all old records so i have write the code like below. may be this code helpful to other

public static void DeleteAllUnclaimedDividendRecords()
       
            DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager();
            Type unclaimedDividendType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.UnclaimedDividend.UnclaimedDividend");
            var myCollection = dynamicModuleManager.GetDataItems(unclaimedDividendType);
            foreach (var item in myCollection)
           
                dynamicModuleManager.DeleteItem(item);
           
            dynamicModuleManager.SaveChanges();
       

Thanks,

Murli

Posted by Community Admin on 02-Mar-2016 00:00

Hi Murli,

Thank you for the shared solution with the community.

Regards,
Svetoslav Manchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

This thread is closed