让我们说我有一张庞大的订单表和另一张更大的订单详情表。
我有两个DataSet
填充SqlDataAdapter
。第一个选择指定客户的订单。第二个应该选择指定客户的订单的订单详细信息(由第一个SqlDataAdapter
选择)。但我无法找到一种方法来优雅地做到这一点。当我添加关系时,我收到一条错误消息,指出'无法启用此约束,因为并非所有值都具有相应的父值'。
我不想在创建关系时禁用约束创建,我也不想选择第二个表的所有行。有没有正确的方法呢?或者唯一的方法是使用f.e构建SQL语句。 IN
条款?现在,正如我所知,如果我在填充表之前添加此关系并且之后,在填充表之后添加关系或填充第二个表时,我将收到此消息并不重要。如果在数据填充之前添加了关系。
System.Data.DataSet dataSet = new System.Data.DataSet();
String connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
System.Data.SqlClient.SqlConnection dbCon = new System.Data.SqlClient.SqlConnection(connectionString);
System.Data.SqlClient.SqlDataAdapter ordersAdapter = new System.Data.SqlClient.SqlDataAdapter(String.Format("SELECT * FROM dbo.Orders Where CustomerId={0}", customerId), dbCon),
detailsAdapter = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM dbo.OrderDetails", dbCon); //Perhaps, I should change this to select only the rows needed, or shouldn't specify SQL at all since it should get all the related rows...
try
{
dbCon.Open();
ordersAdapter.Fill(dataSet, "Orders");
detailsAdapter.Fill(dataSet, "OrderDetails");
}
catch (Exception e)
{
Response.Write("Database error: " + e.Message);
}
finally
{
dbCon.Close();
dbCon.Dispose();
}
dataSet.Relations.Add("Orders2Details", dataSet.Tables["Orders"].Columns["Id"], dataSet.Tables["OrderDetails"].Columns["OrderId"]/*, false*/); //I don't want to use this false
答案 0 :(得分:2)
您需要使用客户的相关订单详细信息填充DetailsAdapter
;只有这样你才能创造两者之间的关系。
所以,像
SELECT * FROM dbo.OrderDetails INNER JOIN dbo.Orders ON OrderDetails.OrderID =
Orders.OrderID WHERE Orders.CustomerId = ...
会做的。
但是,不要在现实中对您的查询这样做。使用存储过程(查询在db服务器上编译,因此执行得更好),或者,如果必须使用内联SQL,请使用SqlParameter
类来避免SQL注入。
可能没有什么能阻止我提供
'1;DROP TABLE Orders;'
作为我想要搜索的客户ID的值,当附加到您的查询中时,它就变成了您真正不想执行的内容。