需要建议 - SQL和ASP.NET

时间:2012-01-12 11:43:22

标签: c# sql

我有一个问题,我尝试自己解决,但没有走得太远(尝试了不同的方法,但所有这些都最终在一大堆代码,最终没有做我需要的)。所以我在这里要求您提供任何建议,解决方案和代码片段。提前谢谢!

我有一个带有表PARTS,ASSEMBLIES和FORMULA的SQL数据库。正如名称所示,组件由零件制成,但也可以由其他组件制成。如何制作组件写在表格FORMULA中。在我的应用程序中,我可以输入已制作的组件数量(增加库存)。但是当我增加装配的库存时,我需要减少相应零件和(子)装配的库存。为了更好地理解,我将用一个例子说明这一点;

PARTS

partID   partStock
  p1       100
  p2       100
  p3       100

ASSEMBLIES

assID    assStock
ass1        10
ass2        10

公式

assID   parts   isAssembly  quantity
ass1     p1         no          1
ass1     p2         no          2
ass1     ass2       yes         1 
ass2     p3         no          2

表的说明:ass1由1x p1 + 2x p2 + 1x ass2(这是另一个程序集)和ass2汇编而成来自2x p3

所以当我将ass1的库存增加10(这不是问题,我可以做到)时,我还需要减少p1(10),p2(20),ass2(10)的库存。如果ass2的股票将<10,我需要减少p3的股票(剩下的数字)。

有人甚至不懂我想做什么吗? :d

欢迎任何建议,非常感谢!哦,我正在用C#编写我的网络应用程序。 :)

编辑:正如评论中指出的那样,我首先寻找一个想法(设计模式)如何实现这一目标。实际的SQL查询和编码不是一个大问题..如果有人有一些有用的代码,它的奖金。 ;)

3 个答案:

答案 0 :(得分:2)

就个人而言,我首先要合并零件和装配表,这使您的模型和计算更容易理解。特别是因为组件也可以是其他组件的一部分。它可能还会使库存概览等其他内容变得更加容易。

您的表格可能如下所示:

<强>部分:

partID, partStock, isAssembly
p1      100        false
p2      100        false
p3      100        false
ass1    10         true
ass2    10         true

<强>公式

partID, part, quantity
ass1    p1    1
ass1    p2    2
ass1    ass2  1
ass2    p3    2

从技术上讲,零件表中的'isAssembly'字段不是必需的,因为当有公式时,零件是一个零件。

要在零件组装时更新库存,您可以递归更新需要构建的其他零件的库存。

“构建”程序集的伪代码大致如下:

void UpdateStock(string partID, int count)
{
    formulas = "select * from FORMULA where partID = " + partID;
    foreach(formula in formulas)
    {
        subPart = "select * from PARTS where partID = " + formula.partID;
        subCount = count * formula.quantity;

        // Check for sufficient stock of this part
        shortage = (subPart.partStock - subCount) * -1;
        if(shortage > 0)
        {
            // When this part is an assembly we can try to 'build' more.
            if(subPart.isAssembly)
            {
                UpdateStock(formula.partID, shortage);
                // Note that when making more isn't possible
                // this will throw an error.
            }
            else
            {
                // Otherwise there simple isn't enough.
                throw Error("Not enough stock");
            }
        }
        // Once we get here there should be enough stock, 
        // either because there was enough in the first place
        // or because we made more. 
        subPart.partStock = subPart.partStock - subCount;
    }

    // Lastly increase the actual stock.
    part = "select * from PARTS where partID = " + partID;
    part.partStock = part.partStock + count;
}

您需要确保在整个功能完成之前不保存对数据库的任何更改,否则您可能在功能失败之前减少了一部分的库存,因为另一部分缺货。

答案 1 :(得分:0)

从我正在阅读的内容和时间限制来看,存储过程可能是最好的。我将如何处理它是在程序集的第一级的所有元素的存储过程中创建临时表(以及实际项的类型与子程序集)。然后,您必须手动继续执行所有递归,直到获得所有子子组件。我会尝试使用一个更复杂的程序集,以确保您获得单个零件,多个子装配以及任何具有子装配等的组合。

将测试版本保存到实际的表格中,这样您就可以查看结果,直到您完成所有调整以及需要减少或适当增加的库存量...然后,一旦看起来很好,然后应用更新加入这一个表,所以它作为一个单独的调用完成,而不是在嵌套的“oops ...错过那个”并且搞乱库存。

答案 2 :(得分:0)

我不确定我完全明白你的意思是什么。 我认为使用CTE可以递归获取所有“PARTS”,并在DbTransaction中执行增加和减少操作。