【发布时间】:2022-01-10 06:26:56
【问题描述】:
我有三个表:Clients、Products 和 Orders
客户:
ClientID - PK
ClientName
产品:
ProductID - PK
ProductName
ProductQuantity
ProductSize
Comments
订单:
OrderID - PK
StartDate
FinishDate
Delivered
Billed
关于我的问题,我有一些不同的答案,即如何加入这些表。我应该为 3 个表的 id 创建第 4 个表还是在订单表中加入客户和产品。事情是一个客户有一个或多个产品的订单。 请指教。
代码更新!
我现在有这个代码,它只适用于客户和产品:
using (var con = new SqlConnection(@"Data Source = GAMEWORK\SQLEXPRESS; Initial Catalog = Tida; Integrated Security = True"))
using (var cmd = new SqlCommand("InsertClients", con) { CommandType = CommandType.StoredProcedure })
using (var cmd2 = new SqlCommand("InsertProducts", con) { CommandType = CommandType.StoredProcedure })
using (var cmd3 = new SqlCommand("InsertOrders", con) { CommandType = CommandType.StoredProcedure })
{
//-----------This works perfect
if (TextBoxClientNou.Enabled)
{
cmd.Parameters.AddWithValue("@NumeClient", TextBoxClientNou.Text);
}
else
{
cmd.Parameters.AddWithValue("@NumeClient", TextBoxClientNou.Text);
}
var IDClientParameter = cmd.Parameters.Add("@IDClient", SqlDbType.Int);
IDClientParameter.Direction = ParameterDirection.Output;
con.Open();
cmd.ExecuteNonQuery();
var IDClient = (int)IDClientParameter.Value;
con.Close();
cmd2.Parameters.Add("@Denumire", SqlDbType.NVarChar, 50);
cmd2.Parameters.Add("@Cantitate", SqlDbType.Int, 50);
cmd2.Parameters.Add("@Dimensiuni", SqlDbType.NVarChar, 50);
cmd2.Parameters.Add("@Comentarii", SqlDbType.NVarChar, 50);
var IDProductParameter = cmd2.Parameters.Add("@IDProdus", SqlDbType.Int);
IDProductParameter.Direction = ParameterDirection.Output;
con.Open();
foreach (ListViewItem item in ListaProduse.Items)
{
cmd2.Parameters["@Denumire"].Value = item.Text;
cmd2.Parameters["@Cantitate"].Value = item.SubItems[1].Text;
cmd2.Parameters["@Dimensiuni"].Value = item.SubItems[1].Text;
cmd2.Parameters["@Comentarii"].Value = item.SubItems[1].Text;
cmd2.ExecuteNonQuery();
} //-----------------------Perfect
//-------This does not work
cmd3.Parameters.Add("@ClientID", SqlDbType.Int).Value = IDClient;
cmd3.Parameters.Add("@ProductID", SqlDbType.Int);
cmd3.Parameters.Add("@DataInceput", SqlDbType.NVarChar).Value = dateTimePicker1.Text;
cmd3.Parameters.Add("@DataSfarsit", SqlDbType.NVarChar).Value = dateTimePicker2.Text;
cmd3.Parameters.Add("@Facturata", SqlDbType.NVarChar, 50).Value = factstatus;
cmd3.Parameters.Add("@Livrata", SqlDbType.NVarChar, 50).Value = livstatus;
cmd3.Parameters.Clear(); //---Only inserts the last product in the order table
var IDProdus = (int)IDProductParameter.Value;
cmd3.Parameters.AddWithValue("@ClientID", IDClient);
cmd3.Parameters.AddWithValue("@ProductID", IDProdus);
cmd3.Parameters.AddWithValue("@DataInceput", dateTimePicker1.Text);
cmd3.Parameters.AddWithValue("@DataSfarsit", dateTimePicker2.Text);
cmd3.Parameters.AddWithValue("@Facturata", factstatus);
cmd3.Parameters.AddWithValue("@Livrata", livstatus);
cmd3.ExecuteNonQuery();
//---------------------------
}
还有这个存储过程:
CREATE PROCEDURE [dbo].[InsertOrders]
@ClientID int,
@ProductID int,
@DataInceput nvarchar(50),
@DataSfarsit nvarchar(50),
@Facturata nvarchar(50),
@Livrata nvarchar(50)
AS
BEGIN
INSERT INTO Comenzi (ClientID, ProductID, DataInceput,DataSfarsit,Factstatus,Livstatus) VALUES (@ClientID, @ProductID, @DataInceput,@DataSfarsit,@Facturata,@Livrata);
END
问题出在 cmd3.parameters.Clear() 上。如果我不使用它,我会收到以下错误:
System.Data.SqlClient.SqlException: 'Procedure or function InsertOrders has too many arguments specified.'
如果我使用它,无论我添加多少,只有表单中的最后一个产品会插入到订单表中。另外,如果我使用 cmd3.ExecuteNonQuery();在 foreach 循环中,它会增加订单 ID 并为列表中的每个产品创建和订购,这是我不想要的。
【问题讨论】:
-
我认为在订单表中加入客户和产品是个好主意,除非您需要更频繁地检索这些记录。如果您多次访问相同的记录,第 4 表可能是提高 sql 性能的好主意。
-
要获得灵感,请查看this simple model 供学生使用。它在订单和产品之间有一个表格。
-
这是关于关系数据库中的表还是关于 C# 中的类?
-
顾问回答:视情况而定。这取决于您的实际场景,但在我的经验中,enigmativity's answer 的观点是现实世界场景中最常用的。这应该是您问题的公认答案。
-
这听起来真的像你通过编辑完全改变了你在这个问题中寻找的东西。