示例#1
0
        public virtual int PrefetchProductVariantAttributes(IEnumerable <string> attributesXml)
        {
            if (attributesXml == null || !attributesXml.Any())
            {
                return(0);
            }

            // Determine uncached attributes
            var unfetched = attributesXml
                            .Where(xml => xml.HasValue())
                            .Distinct()
                            .Where(xml => !_requestCache.Contains(ATTRIBUTEVALUES_BY_XML_KEY.FormatInvariant(xml)))
                            .ToArray();

            var infos = new List <AttributeMapInfo>(unfetched.Length);

            foreach (var xml in unfetched)
            {
                var valueIds   = new HashSet <int>();
                var map        = DeserializeProductVariantAttributes(xml);
                var attributes = _productAttributeService.GetProductVariantAttributesByIds(map.Keys);

                foreach (var attribute in attributes)
                {
                    // Only types that have attribute values! Otherwise entered text is misinterpreted as an attribute value id.
                    if (!attribute.ShouldHaveValues())
                    {
                        continue;
                    }

                    var ids =
                        from id in map[attribute.Id]
                        where id.HasValue()
                        select id.ToInt();

                    valueIds.UnionWith(ids);
                }

                var info = new AttributeMapInfo
                {
                    AttributesXml   = xml,
                    DeserializedMap = map,
                    AllValueIds     = valueIds.ToArray()
                };

                infos.Add(info);
            }

            // Get all value ids across all maps (each map has many attributes)
            var allValueIds = infos.SelectMany(x => x.AllValueIds)
                              .Distinct()
                              .ToArray();

            // Load ALL requested attribute values into a single dictionary in one go (key is Id)
            var attributeValues = _productAttributeService.GetProductVariantAttributeValuesByIds(allValueIds).ToDictionarySafe(x => x.Id);

            // Create a single cache entry for each passed xml
            foreach (var info in infos)
            {
                var cachedValues = new List <ProductVariantAttributeValue>();

                // Ensure value id order in cached result list is correct
                foreach (var id in info.AllValueIds)
                {
                    if (attributeValues.TryGetValue(id, out var value))
                    {
                        cachedValues.Add(value);
                    }
                }

                // Put it in cache
                var cacheKey = ATTRIBUTEVALUES_BY_XML_KEY.FormatInvariant(info.AttributesXml);
                _requestCache.Put(cacheKey, cachedValues);
            }

            return(unfetched.Length);
        }