【问题标题】:Save order data to local database将订单数据保存到本地数据库
【发布时间】:2015-05-15 11:47:45
【问题描述】:

我正在使用 C# 创建一个 Windows 窗体应用程序。如何创建本地数据库表来保存下述数据?目前我的数据表由“inv_Id”、“Item_Id”和“quantity”列组成。我知道我需要创建列来存储下面的每个数据项,但我不知道如何构建表格。

  • item={椅子、桌子、笔、拇指驱动器}
  • 价格={5,10,2,48}
  • 小计
  • 总计

我是 C# 的新手。我对此进行了搜索,并找到了诸如https://www.youtube.com/watch?v=I5qvyyhUKfY

之类的内容

数据显示在列表框中,如下所示:

订购商品:椅子 价格:$5.00
订购商品:桌子价格:$10.00
订购商品:钢笔 价格:$2.00
订购商品:拇指驱动器价格:$48.00

小计:$65.00 税:$3.90 总计:$68.90

我的目的是创建发票,然后在计算完所有内容后将其保存在数据库中。

这是我获取数据的代码,将数据库中的数据加载到下拉列表中(供用户选择他们想要购买的商品),然后(客户选择的商品将列在 listOuput 框中进行计算)用户将选择项目,然后列表框将显示所选输出并像收据一样计算总数。

计算后,我希望将 listOutput 框中的所有数据存储到我的数据库中,但是我在这里遇到了问题。

问题:我不知道如何将所有数据从列表框中移动到 数据库,并将它们在结构中链接在一起。

public partial class Select_Item : Form
{
    SqlConnection con = new SqlConnection( @"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\oo\Documents\Data.mdf;Integrated Security=True;Connect Timeout=30");
    SqlDataAdapter da = new SqlDataAdapter();
    DataTable dt = new DataTable();

    public struct Orders
    {
        public string item;
        public double price;           
    }

    const double TAX=0.06;
    Orders order = new Orders();
    static double subtotal=0;
    static double totalTaxes=0;  
    static double total;
    string finalBill = "FINAL BILL: \n";

    public Select_Item()
    {
        InitializeComponent();       
    }

    private void getValues(string custOrder)
    {          
        order.item = custOrder;

        String a = comboBox1.Text;
        order.price = Convert.ToDouble(custOrder);
        listOutput.Items.Add("Price: " + order.price);

        finalBill += "Ordered Item: " + a + "\nPrice: " + order.price.ToString("C2") + "\n";
        updateBill();           
    }

    private void updateBill()
    {
        subtotal += order.price;
        total += order.price + (order.price * TAX);
        totalTaxes += order.price * TAX;
        listOutput.Items.Clear();
        listOutput.Items.AddRange(finalBill.Split('\n'));
        listOutput.Items.Add("Subtotal:" + subtotal.ToString("C2"));
        listOutput.Items.Add("Tax:" + totalTaxes.ToString("C2"));
        listOutput.Items.Add("Total:" + total.ToString("C2"));
    }
    private void dropdownSelection(object sender, EventArgs e)
    {
       if (sender == comboBox1)
        System.Diagnostics.Debug.WriteLine("test " + comboBox1.SelectedValue.ToString());     
        getValues(comboBox1.SelectedValue.ToString());  
    }

编辑代码:

 private void StoreData()
        {
            int invoiceID;


            using (var con1 = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\choo\Documents\Data.mdf;Integrated Security=True;Connect Timeout=30"))
            {
                con.Close();
                con.Open();
                using (var cmd = con.CreateCommand())
                {
                    cmd.CommandText = @"insert into Invoice(subtotal,tax,total) values (@subtotal,@tax,@total); select SCOPE_IDENTITY() as InvoiceID;";
                    cmd.Parameters.AddWithValue("@subtotal", subtotal);
                    cmd.Parameters.AddWithValue("@tax", tax);
                    cmd.Parameters.AddWithValue("@total", total);
                    using (var reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())

                            invoiceID = (int)reader["InvoiceID"];

                    }
                }
                foreach (var item in OrderItems.Rows)
                {
                    using (var cmd = con.CreateCommand())
                    {

                        cmd.CommandText = @"insert into InvoiceItem(invoiceID,Item_Id,quantity) values (@invoiceID,@Item_Id,@quantity);";
                       // cmd.Parameters.AddWithValue("@InvoiceID", invoiceID);
                        cmd.Parameters.AddWithValue("@invoiceID", Convert.ToInt32("invoiceID"));
                        cmd.Parameters.AddWithValue("@Item_Id", Convert.ToInt32("Item_Id"));
                        cmd.Parameters.AddWithValue("@quantity", Convert.ToInt32("quantity"));
                        cmd.ExecuteNonQuery();



                    }
                }
            }
        }

【问题讨论】:

  • 我已经编辑了您的问题,表明您正在将数据保存到 SQL 数据库。在我看来就是这种情况,但如果您不使用 SQL,请编辑您的问题以说明您是如何存储数据的。另外,我不确定您是在询问如何构建 SQL 表,还是在询问如何在 winforms 应用程序内移动数据。你能再解释一下吗?

标签: c# sql winforms schema storage


【解决方案1】:

我假设您将数据保存到 SQL 数据库。您的 invoice 和 item 表共享多对多关系,因此您应该使用第三个表将它们链接在一起。

  • 发票:invoiceID、小计、税金、总计
  • 商品:商品 ID、价格
  • InvoiceItem:invoiceItemID、invoiceID、itemID、数量

InvoiceItem 表具有其他两个的外键。这样您就可以保持发票和项目数据分开且干净;有 10 种不同的“笔”物品没有任何问题,因为 10 种不同的订单包括一支笔。

请注意,您可以通过从该发票中选择所有项目并计算数量 * 价格的总和来计算 Invoice.subtotal。为方便起见,我建议将其包含在 Invoice 表中。

要将订单输入数据库,您需要这样的东西:

private void StoreData()
{
  int invoiceID;
  using(var con = new SqlConnection( @"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\oo\Documents\Data.mdf;Integrated Security=True;Connect Timeout=30"))
  {
    con.Open();
    using(var cmd = con.CreateCommand())
    {
      cmd.CommandText = @"insert into Invoice(subtotal,tax,total) values (@subtotal,@tax,@total); select SCOPE_IDENTITY() as InvoiceID;";
      cmd.Parameters.AddWithValue("@subtotal",subtotal);
      cmd.Parameters.AddWithValue("@tax",tax);
      cmd.Parameters.AddWithValue("@total",total);
      using(var reader = cmd.ExecuteReader())
      {
        if(reader.Read())
          invoiceID = cmd.GetInt32("InvoiceID");
      }
    }
    foreach(var item in orderItems)
    {
      using(var cmd = con.CreateCommand())
      {
        cmd.CommandText = @"insert into InvoiceItem(InvoiceID,ItemID,quantity) values (@InvoiceID,@ItemID,@quantity);";
        cmd.Parameters.AddWithValue("@InvoiceID",invoiceID);
        cmd.Parameters.AddWithValue("@ItemID",item.ItemID);
        cmd.Parameters.AddWithValue("@quantity",item.Quantity);
        cmd.ExecuteNonQuery();
      }
    }
  }
}

请理解,这是您需要做什么的基本概念。我也没有在 IDE 中实际检查它就编写了它,所以可能有一两个错误。重要的是,它与您现有的代码不兼容。以下是您需要执行的操作:

  • 为您的订单创建一个名为orderItems 的项目集合。此集合中的每个项目都应该是某种对象,代表您的 ListBox 中的一行。请注意,您的 OrderItems 结构不足以表示单个项目(您能说出原因吗?)。现在,您将事物作为数据字符串传递。您需要使用真实的对象才能掌握 OOP 的强大功能。
  • 删除表单顶部的 SqlConnection 声明。您不希望连接对象只是坐在那里。 using 块确保有限的生命周期,并确保对象被正确关闭和处置。如果您在其他地方使用此对象(例如,获取项目列表以向您的用户显示),那么您需要修改该代码以使用此模式。
  • 确定将 itemID、小计、税款和总计导入此方法的好方法。您可以将它们作为参数传递,也可以使用对象。

可以对我发布的代码和您已经拥有的代码进行很多改进。这仅意味着基本功能就足够了。以下是我留给你作为练习的事情,但你应该这样做:

  • 错误处理
  • 创建适当的项目对象集合并将其绑定到您的 UI 元素
  • 从商品对象而非 UI 元素(ComboBox 和 ListBox)中获取价格和 itemID 等静态数据
  • 更加熟悉数据库交互功能,以便了解其工作原理

【讨论】:

  • 是的,我已经创建了上面的表,但是我提取了“Total”的数据,然后放入“total”列的发票表中。我需要做一些条件来提取数据并放入各个列中
  • 在 winforms 应用程序内进行所有计算,并将每个数字存储在发票表的 SQL 列中。这将使您更轻松地使用您的数据库来处理诸如向客户发送发票副本等事情。
  • 是的,我已经进行了计算,但是我希望将我的数据存储在数据库中,我现在可以计算但没有存储。我已经发布了我的代码如上。
  • 嗨,为什么我会收到“无效的对象名称'发票'。”的错误?(在行“使用(var reader = cmd.ExecuteReader())”)我已经创建了数据库表和列完全一样...
  • 我尝试添加虚拟 invoiceID,cmd.CommandText = @"insert into Invoice(invoiceID, subtotal,tax,total) 值 (1, @subtotal,@tax,@total); 选择 SCOPE_IDENTITY () 作为 InvoiceID;";
猜你喜欢
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 2017-03-06
相关资源
最近更新 更多