/// <summary>
        /// 判断是否匹配
        /// </summary>
        public bool IsMatched(ProductMatchParameters parameters, ProductMatchedData data)
        {
            // 获取规格的条件
            // 格式 [ { PropertyId: ..., PropertyValueId: ... }, ... ]
            var exceptedProperties = data.Conditions.GetProperties();

            if (exceptedProperties == null || !exceptedProperties.Any())
            {
                return(true);                // 没有指定条件
            }
            // 判断参数中的规格值列表是否包含条件中的所有规格值
            // 例如 参数 { 颜色: 黑色, 尺码: XXS, 款式: 2013 }, 条件 { 颜色: 黑色, 尺码: XXS }时匹配成功
            // 参数的格式同上
            var incomeProperties = parameters.GetProperties();

            if (incomeProperties == null || !incomeProperties.Any())
            {
                return(false);                // 有指定条件,但参数中没有包含任何规格值
            }
            var incomePropertiesMapping = new Dictionary <long, long?>();

            foreach (var obj in incomeProperties)
            {
                incomePropertiesMapping[obj.PropertyId] = obj.PropertyValueId;
            }
            return(exceptedProperties.All(obj => {
                return incomePropertiesMapping.GetOrDefault(obj.PropertyId) == obj.PropertyValueId;
            }));
        }
        /// <summary>
        /// 获取描述,没有时返回null
        /// </summary>
        public string GetDescription(Database.Product product, ProductMatchParameters parameters)
        {
            var properties = parameters.GetProperties();

            if (properties == null || properties.Count <= 0)
            {
                return(null);
            }
            var parts = new List <string>();

            foreach (var productToPropertyValue in product.FindPropertyValuesFromPropertyParameters(properties))
            {
                parts.Add(string.Format("{0}: {1}",
                                        new T(productToPropertyValue.Property.Name),
                                        new T(productToPropertyValue.PropertyValueName)));
            }
            return(string.Join(" ", parts));
        }
        /// <summary>
        /// 判断商品匹配参数是否部分相等
        /// </summary>
        public bool IsPartialEqual(
            ProductMatchParameters lhs, ProductMatchParameters rhs)
        {
            var propertiesLhs = lhs.GetProperties();
            var propertiesRhs = rhs.GetProperties();

            if (propertiesLhs == null && propertiesRhs == null)
            {
                return(true);
            }
            else if (propertiesLhs == null || propertiesRhs == null)
            {
                return(false);
            }
            var disinctCount = propertiesLhs.Concat(propertiesRhs)             // 计算并集去除重复后的大小
                               .Select(p => new Pair <long, long>(p.PropertyId, p.PropertyValueId)).Distinct().Count();

            return(propertiesLhs.Count == disinctCount && propertiesLhs.Count == propertiesRhs.Count);
        }