/// <summary>
        /// The persist updated item.
        /// </summary>
        /// <param name="entity">
        /// The entity.
        /// </param>
        protected override void PersistUpdatedItem(IProductVariant entity)
        {
            if (!MandateProductVariantRules(entity))
            {
                return;
            }

            Mandate.ParameterCondition(!SkuExists(entity.Sku, entity.Key), "Entity cannot be updated.  The sku already exists.");

            ((Entity)entity).UpdatingEntity();
            ((ProductVariant)entity).VersionKey = Guid.NewGuid();

            var factory = new ProductVariantFactory(
                pa => ((ProductVariant)entity).ProductAttributes,
                ci => ((ProductVariant)entity).CatalogInventoryCollection,
                dc => ((ProductVariant)entity).DetachedContents);

            var dto = factory.BuildDto(entity);

            // update the variant
            Database.Update(dto);

            SaveCatalogInventory(entity);

            SaveDetachedContents(entity);

            entity.ResetDirtyProperties();

            RemoveProductsFromRuntimeCache(new[] { entity.ProductKey });
        }
        /// <summary>
        /// The persist new item.
        /// </summary>
        /// <param name="entity">
        /// The entity.
        /// </param>
        protected override void PersistNewItem(IProductVariant entity)
        {
            if (!MandateProductVariantRules(entity))
            {
                return;
            }

            Mandate.ParameterCondition(!SkuExists(entity.Sku), "The sku must be unique");

            ((Entity)entity).AddingEntity();

            ((ProductVariant)entity).VersionKey = Guid.NewGuid();

            var factory = new ProductVariantFactory(
                pa => ((ProductVariant)entity).ProductAttributes,
                ci => ((ProductVariant)entity).CatalogInventoryCollection,
                dc => ((ProductVariant)entity).DetachedContents);

            var dto = factory.BuildDto(entity);

            // insert the variant
            Database.Insert(dto);
            entity.Key = dto.Key; // to set HasIdentity

            Database.Insert(dto.ProductVariantIndexDto);
            ((ProductVariant)entity).ExamineId = dto.ProductVariantIndexDto.Id;

            // insert associations for every attribute
            foreach (var association in entity.Attributes.Select(att => new ProductVariant2ProductAttributeDto()
            {
                ProductVariantKey = entity.Key,
                OptionKey = att.OptionKey,
                ProductAttributeKey = att.Key,
                UpdateDate = DateTime.Now,
                CreateDate = DateTime.Now
            }))
            {
                Database.Insert(association);
            }

            SaveCatalogInventory(entity);

            SaveDetachedContents(entity);

            entity.ResetDirtyProperties();

            RuntimeCache.ClearCacheItem(Cache.CacheKeys.GetEntityCacheKey <IProduct>(entity.ProductKey));
        }
        /// <summary>
        /// Gets the product variant.
        /// </summary>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <returns>
        /// The <see cref="IProductVariant"/>.
        /// </returns>
        protected override IProductVariant PerformGet(Guid key)
        {
            var sql = GetBaseQuery(false)
                      .Where(GetBaseWhereClause(), new { Key = key });

            var dto = Database.Fetch <ProductDto, ProductVariantDto, ProductVariantIndexDto>(sql).FirstOrDefault();

            if (dto == null || dto.ProductVariantDto == null)
            {
                return(null);
            }

            var factory = new ProductVariantFactory(_productOptionRepository.GetProductAttributeCollectionForVariant, GetCategoryInventoryCollection, GetDetachedContentCollection);
            var variant = factory.BuildEntity(dto.ProductVariantDto);

            variant.ResetDirtyProperties();

            return(variant);
        }
        protected override void PersistUpdatedItem(IProductVariant entity)
        {
            if (!MandateProductVariantRules(entity))
            {
                return;
            }

            Mandate.ParameterCondition(!SkuExists(entity.Sku, entity.Key), "Entity cannot be updated.  The sku already exists.");

            ((Entity)entity).UpdatingEntity();

            var factory = new ProductVariantFactory(((ProductVariant)entity).ProductAttributes, ((ProductVariant)entity).CatalogInventoryCollection);
            var dto     = factory.BuildDto(entity);

            // update the variant
            Database.Update(dto);

            SaveCatalogInventory(entity);

            entity.ResetDirtyProperties();

            RuntimeCache.ClearCacheItem(Cache.CacheKeys.GetEntityCacheKey <IProduct>(entity.ProductKey));
        }
        /// <summary>
        /// The persist new items.
        /// </summary>
        /// <param name="entities">
        /// The entities.
        /// </param>
        public void PersistNewItems(IEnumerable <IProductVariant> entities)
        {
            var productVariants = entities as IProductVariant[] ?? entities.ToArray();

            if (!MandateProductVariantRules(productVariants))
            {
                return;
            }

            //// Mandate.ParameterCondition(!SkuExists(entity.Sku), "The sku must be unique");
            var dtos = new List <ProductVariantDto>();

            foreach (var entity in productVariants)
            {
                ((ProductBase)entity).AddingEntity();
                var factory = new ProductVariantFactory();
                dtos.Add(factory.BuildDto(entity));
            }

            // insert the variants
            BulkInsertRecordsWithKey <ProductVariantDto>(dtos);
            BulkInsertRecordsWithKey <ProductVariantIndexDto>(dtos.Select(v => v.ProductVariantIndexDto));

            // We have to look up the examine ids
            var idDtos = Database.Fetch <ProductVariantIndexDto>("WHERE productVariantKey IN (@pvkeys)", new { @pvkeys = dtos.Select(x => x.Key) });

            foreach (var entity in productVariants)
            {
                var dto = dtos.FirstOrDefault(d => d.VersionKey == entity.VersionKey);
                // ReSharper disable once PossibleNullReferenceException
                entity.Key = dto.Key; // to set HasIdentity

                var productVariantIndexDto = idDtos.FirstOrDefault(id => id.ProductVariantKey == dto.Key);
                if (productVariantIndexDto != null)
                {
                    ((ProductVariant)entity).ExamineId = productVariantIndexDto.Id;
                }

                foreach (var inv in entity.CatalogInventories)
                {
                    ((CatalogInventory)inv).ProductVariantKey = entity.Key;
                }
            }

            var xrefs = new List <ProductVariant2ProductAttributeDto>();

            foreach (var v in productVariants.ToArray())
            {
                var associations = v.Attributes.Select(x =>
                                                       new ProductVariant2ProductAttributeDto
                {
                    ProductVariantKey   = v.Key,
                    OptionKey           = x.OptionKey,
                    ProductAttributeKey = x.Key,
                    UpdateDate          = DateTime.Now,
                    CreateDate          = DateTime.Now
                });

                xrefs.AddRange(associations);
            }

            BulkInsertRecordsWithKey <ProductVariant2ProductAttributeDto>(xrefs);

            SaveCatalogInventory(productVariants);

            SaveDetachedContents(productVariants);

            foreach (var entity in productVariants)
            {
                entity.ResetDirtyProperties();
                RuntimeCache.ClearCacheItem(Cache.CacheKeys.GetEntityCacheKey <IProduct>(entity.ProductKey));
            }
        }