填充仅与主表行相关的从属表

时间:2014-09-02 20:43:36

标签: c# datatable dataset relationship sqldataadapter

让我们说我有一张庞大的订单表和另一张更大的订单详情表。

我有两个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

1 个答案:

答案 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的值,当附加到您的查询中时,它就变成了您真正不想执行的内容。