public void DoImport(Stream stream, PlatformExportManifest manifest, Action <ExportImportProgressInfo> progressCallback)
        {
            var progressInfo       = new ExportImportProgressInfo();
            var productsTotalCount = 0;

            using (StreamReader streamReader = new StreamReader(stream))
                using (JsonTextReader reader = new JsonTextReader(streamReader))
                {
                    while (reader.Read())
                    {
                        if (reader.TokenType == JsonToken.PropertyName)
                        {
                            if (reader.Value.ToString() == "Catalogs")
                            {
                                reader.Read();
                                var catalogs = _serializer.Deserialize <Catalog[]>(reader);
                                progressInfo.Description = $"{ catalogs.Count() } catalogs importing...";
                                progressCallback(progressInfo);
                                _catalogService.Update(catalogs);
                            }
                            else if (reader.Value.ToString() == "Categories")
                            {
                                reader.Read();
                                var categories = _serializer.Deserialize <Category[]>(reader);
                                progressInfo.Description = $"{ categories.Count() } categories importing...";
                                progressCallback(progressInfo);
                                _categoryService.Update(categories);
                                if (manifest.HandleBinaryData)
                                {
                                    ImportImages(categories);
                                }
                            }
                            else if (reader.Value.ToString() == "Properties")
                            {
                                reader.Read();
                                var properties = _serializer.Deserialize <Property[]>(reader);
                                progressInfo.Description = $"{ properties.Count() } properties importing...";
                                progressCallback(progressInfo);
                                _propertyService.Update(properties);
                            }
                            else if (reader.Value.ToString() == "ProductsTotalCount")
                            {
                                productsTotalCount = reader.ReadAsInt32() ?? 0;
                            }
                            else if (reader.Value.ToString() == "Products")
                            {
                                reader.Read();

                                if (reader.TokenType == JsonToken.StartArray)
                                {
                                    reader.Read();

                                    var associationBackupMap = new Dictionary <string, ICollection <ProductAssociation> >();
                                    var products             = new List <CatalogProduct>();
                                    var productsCount        = 0;
                                    //Import products
                                    while (reader.TokenType != JsonToken.EndArray)
                                    {
                                        var product = _serializer.Deserialize <CatalogProduct>(reader);
                                        //Do not save associations withing product to prevent dependency conflicts in db
                                        //we will save separateley after product import
                                        if (!product.Associations.IsNullOrEmpty())
                                        {
                                            associationBackupMap[product.Id] = product.Associations;
                                        }
                                        product.Associations = null;
                                        products.Add(product);
                                        productsCount++;
                                        reader.Read();
                                        if (productsCount % _batchSize == 0 || reader.TokenType == JsonToken.EndArray)
                                        {
                                            _itemService.Update(products.ToArray());
                                            if (manifest.HandleBinaryData)
                                            {
                                                ImportImages(products.ToArray());
                                            }

                                            products.Clear();
                                            if (productsTotalCount > 0)
                                            {
                                                progressInfo.Description = $"{ productsCount } of { productsTotalCount } products imported";
                                            }
                                            else
                                            {
                                                progressInfo.Description = $"{ productsCount } products imported";
                                            }
                                            progressCallback(progressInfo);
                                        }
                                    }
                                    //Import products associations separately to avoid DB constrain violation
                                    var totalProductsWithAssociationsCount = associationBackupMap.Count();
                                    progressInfo.Description = $"{ totalProductsWithAssociationsCount } products associations importing...";
                                    progressCallback(progressInfo);
                                    for (int i = 0; i < totalProductsWithAssociationsCount; i += _batchSize)
                                    {
                                        var fakeProducts = new List <CatalogProduct>();
                                        foreach (var pair in associationBackupMap.Skip(i).Take(_batchSize))
                                        {
                                            var fakeProduct = new CatalogProduct
                                            {
                                                Id           = pair.Key,
                                                Associations = pair.Value
                                            };
                                            fakeProducts.Add(fakeProduct);
                                        }
                                        _associationService.SaveChanges(fakeProducts.ToArray());
                                        progressInfo.Description = $"{ Math.Min(totalProductsWithAssociationsCount, i + _batchSize) } of { totalProductsWithAssociationsCount } products associations imported";
                                        progressCallback(progressInfo);
                                    }
                                }
                            }
                        }
                    }
                }
        }
示例#2
0
        public void DoImport(Stream stream, PlatformExportManifest manifest, Action <ExportImportProgressInfo> progressCallback)
        {
            var progressInfo              = new ExportImportProgressInfo();
            var productsTotalCount        = 0;
            var propDictItemTotalCount    = 0;
            var propertiesWithForeignKeys = new List <Property>();

            using (var streamReader = new StreamReader(stream))
                using (var reader = new JsonTextReader(streamReader))
                {
                    while (reader.Read())
                    {
                        if (reader.TokenType == JsonToken.PropertyName)
                        {
                            if (reader.Value.ToString() == "Catalogs")
                            {
                                reader.Read();
                                var catalogs = _serializer.Deserialize <Catalog[]>(reader);
                                progressInfo.Description = $"{ catalogs.Count() } catalogs are importing…";
                                progressCallback(progressInfo);
                                _catalogService.Update(catalogs);
                            }
                            else if (reader.Value.ToString() == "Categories")
                            {
                                reader.Read();
                                var categories = _serializer.Deserialize <Category[]>(reader);
                                progressInfo.Description = $"{ categories.Count() } categories are importing…";
                                progressCallback(progressInfo);
                                _categoryService.Update(categories);
                                if (manifest.HandleBinaryData)
                                {
                                    ImportImages(categories, progressInfo);
                                }
                            }
                            else if (reader.Value.ToString() == "Properties")
                            {
                                reader.Read();
                                var properties = _serializer.Deserialize <Property[]>(reader);
                                foreach (var property in properties)
                                {
                                    if (property.CategoryId != null || property.CatalogId != null)
                                    {
                                        propertiesWithForeignKeys.Add(property.Clone() as Property);
                                        //Need to reset property foreign keys to prevent FK violation during  inserting into database
                                        property.CategoryId = null;
                                        property.CatalogId  = null;
                                    }
                                }
                                progressInfo.Description = $"{ properties.Count() } properties are importing…";
                                progressCallback(progressInfo);
                                _propertyService.Update(properties);
                            }
                            else if (reader.Value.ToString() == "ProductsTotalCount")
                            {
                                productsTotalCount = reader.ReadAsInt32() ?? 0;
                            }
                            else if (reader.Value.ToString() == "PropertyDictionaryItemsTotalCount")
                            {
                                propDictItemTotalCount = reader.ReadAsInt32() ?? 0;
                            }
                            else if (reader.Value.ToString() == "PropertyDictionaryItems")
                            {
                                reader.Read();
                                if (reader.TokenType == JsonToken.StartArray)
                                {
                                    reader.Read();

                                    var propDictItems      = new List <PropertyDictionaryItem>();
                                    var propDictItemsCount = 0;
                                    //Import property dcitonary items
                                    while (reader.TokenType != JsonToken.EndArray)
                                    {
                                        var propDictItem = AbstractTypeFactory <PropertyDictionaryItem> .TryCreateInstance();

                                        propDictItem = _serializer.Deserialize(reader, propDictItem.GetType()) as PropertyDictionaryItem;
                                        propDictItems.Add(propDictItem);
                                        propDictItemsCount++;
                                        reader.Read();
                                        if (propDictItemsCount % BatchSize == 0 || reader.TokenType == JsonToken.EndArray)
                                        {
                                            _propertyDictionaryService.SaveChanges(propDictItems.ToArray());
                                            propDictItems.Clear();
                                            if (propDictItemsCount > 0)
                                            {
                                                progressInfo.Description = $"{ propDictItemsCount } of { propDictItemTotalCount } dictionary items have been imported";
                                            }
                                            else
                                            {
                                                progressInfo.Description = $"{ propDictItemsCount } dictionary items have been imported";
                                            }
                                            progressCallback(progressInfo);
                                        }
                                    }
                                }
                            }
                            else if (reader.Value.ToString() == "Products")
                            {
                                reader.Read();

                                if (reader.TokenType == JsonToken.StartArray)
                                {
                                    reader.Read();

                                    var associationBackupMap = new Dictionary <string, ICollection <ProductAssociation> >();
                                    var products             = new List <CatalogProduct>();
                                    var productsCount        = 0;
                                    //Import products
                                    while (reader.TokenType != JsonToken.EndArray)
                                    {
                                        var product = AbstractTypeFactory <CatalogProduct> .TryCreateInstance();

                                        product = _serializer.Deserialize(reader, product.GetType()) as CatalogProduct;
                                        //Do not save associations withing product to prevent dependency conflicts in db
                                        //we will save separateley after product import
                                        if (!product.Associations.IsNullOrEmpty())
                                        {
                                            associationBackupMap[product.Id] = product.Associations;
                                        }
                                        product.Associations = null;
                                        products.Add(product);
                                        productsCount++;
                                        reader.Read();
                                        if (productsCount % BatchSize == 0 || reader.TokenType == JsonToken.EndArray)
                                        {
                                            _itemService.Update(products.ToArray());
                                            if (manifest.HandleBinaryData)
                                            {
                                                ImportImages(products.ToArray(), progressInfo);
                                            }

                                            products.Clear();
                                            if (productsTotalCount > 0)
                                            {
                                                progressInfo.Description = $"{ productsCount } of { productsTotalCount } products have been imported";
                                            }
                                            else
                                            {
                                                progressInfo.Description = $"{ productsCount } products have been imported";
                                            }
                                            progressCallback(progressInfo);
                                        }
                                    }
                                    //Import products associations separately to avoid DB constrain violation
                                    var totalProductsWithAssociationsCount = associationBackupMap.Count;
                                    progressInfo.Description = $"{ totalProductsWithAssociationsCount } products associations are importing…";
                                    progressCallback(progressInfo);
                                    for (var i = 0; i < totalProductsWithAssociationsCount; i += BatchSize)
                                    {
                                        var fakeProducts = new List <CatalogProduct>();
                                        foreach (var pair in associationBackupMap.Skip(i).Take(BatchSize))
                                        {
                                            var fakeProduct = AbstractTypeFactory <CatalogProduct> .TryCreateInstance();

                                            fakeProduct.Id           = pair.Key;
                                            fakeProduct.Associations = pair.Value;
                                            fakeProducts.Add(fakeProduct);
                                        }
                                        _associationService.SaveChanges(fakeProducts.ToArray());
                                        progressInfo.Description = $"{ Math.Min(totalProductsWithAssociationsCount, i + BatchSize) } of { totalProductsWithAssociationsCount } products associations imported";
                                        progressCallback(progressInfo);
                                    }
                                }
                            }
                        }
                    }
                }

            //Update property associations after all required data are saved (Catalogs and Categories)
            if (propertiesWithForeignKeys.Count > 0)
            {
                progressInfo.Description = $"Updating {propertiesWithForeignKeys.Count} property associations…";
                progressCallback(progressInfo);

                var totalCount = propertiesWithForeignKeys.Count;
                for (var i = 0; i < totalCount; i += BatchSize)
                {
                    _propertyService.Update(propertiesWithForeignKeys.Skip(i).Take(BatchSize).ToArray());
                    progressInfo.Description = $"{ Math.Min(totalCount, i + BatchSize) } of { totalCount } property associations updated.";
                    progressCallback(progressInfo);
                }
            }
        }