65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在目录中管理具有不同价格的产品选项

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.15/5 (6投票s)

2009年5月4日

CPOL

2分钟阅读

viewsIcon

26488

downloadIcon

302

本文提供了一种在目录中管理产品选项的简单解决方案。此解决方案适用于任意数量的选项。

引言

本文为管理产品目录中不同产品选项(例如,尺寸、颜色等)的问题提供了一种简单且可扩展的解决方案。

Data Model

在下图中,你可以看到 LINQ DBML 预览。每个产品可以与任意数量的选项(尺寸、颜色等)相关联,并且每个选项都与任意数量的值(红色、蓝色、小号、中号等)相关联。表 *Combination* 和 *CombinationDetail* 用于存储不同选项值的组合的价格。

ProductOptions

可下载的 zip 文件中提供的 SQL 脚本将创建数据库、表、关系,并在其中填充示例数据。

在我们的示例数据库中,产品“Test Product”具有三个属性(颜色、尺寸和保修)。假设组合 Red-Small-WithWarranty 的价格 = 200。这意味着我们将在 *Combination* 表中有一行价格 = 200,并在 *CombinationDetail* 表中为每个值有一行。

此数据结构允许为产品分配任意数量的选项,并允许每个选项具有任意数量的值。

Windows 客户端应用程序

Screenshot

可下载的 zip 文件还包含一个 Windows Forms 项目。该项目允许用户为一组特定的选项值生成所有可能的组合,并管理不同组合的价格。

请在 *app.config* 文件中自行调整连接字符串。

生成组合并定义所有不同的价格后,就可以选择一组不同的值并检查其价格。

代码

Windows 客户端应用程序中有两个有趣的代码片段。类 CombinationBuilder 用于生成一组选项值的所有可能的组合。

public class CombinationBuilder
{
    private Dictionary<int,> _counters;
    private List<string> _combinationList;

    public CombinationBuilder(Dictionary<int,> counters)
    {
        _counters = counters;
    }

    public List<string> CombinationList
    {
        get
        {
            return _combinationList;
        }
        set
        {
            _combinationList = value;
        }
    }

    public void BuildCombinationString()
    {
        CombinationList = new List<string>();
        recursion(-1, "");
    }

    private void recursion(int level, string previousString)
    {
        level++;
        for (int i = 0; i < _counters[level]; i++)
        {
            string currentString = 
              previousString + i.ToString() + ",";
            
            if (level+1 < _counters.Count)
            {
                recursion(level, currentString);
            }
            else
            {
                if (currentString.Length > 0)
                    currentString = 
                      currentString.Remove(currentString.Length - 1);
                CombinationList.Add(currentString);
            }
        }
    }

}

此类只是生成一个如下所示的字符串列表

0,0,0
0,0,1
0,0,2
1,0,0
....
3,2,2

此列表用作在数据库中生成数据的架构。

另一个有趣的代码是获取给定值的组合的价格的查询。该查询是使用 LINQ to SQL 和 PredicateBuilder 类生成的 (http://www.albahari.com/nutshell/predicatebuilder.aspx)。

private void LoadPrice()
{
    int optionCount = 0;
    var predicate = PredicateBuilder.False<combinationdetail>();
    foreach (var control in grpOptions.Controls)
    {
        if (control.GetType() == typeof(SingleOption))
        {
            int optionValueId = (control as SingleOption).SelectedOptionValueId;
            predicate = predicate.Or(p => p.OptionValueId == optionValueId);
            optionCount++;
        }
    }

    ProductOptionsDataContext productOptionsDataContext =
        new ProductOptionsDataContext();
    var combination = productOptionsDataContext
                        .CombinationDetails
                        .Where(predicate)
                        .GroupBy(p=> p.Combination)
                            .Where(p=> p.Count()==optionCount)
                            .Select(p=>p.Key);

    decimal price = 0;
    if (combination.Count() == 1)
    {
        price = combination.Single().Price;
    }
    else
    {
        //If no combination is found the main product price will be displayed
        price = SelectedProduct.Price;
    }
    lblPrice.Text = string.Format("Price = {0}", price.ToString());
}

注意

大量的选项和选项值可能会生成大量的不同组合。也许在这种情况下,为任何组合定义不同的价格没有用处,因此最好不要在数据库中生成所有组合,而只生成那些具有特定价格的组合。示例代码中未提供此解决方案,但很容易实现。

© . All rights reserved.