Заполнение ведомой таблицы только связанными со строками основной таблицы

1

Допустим, у меня есть огромная таблица заказов, а другая - гораздо большая таблица деталей заказа.

У меня есть DataSet который заполняется из двух SqlDataAdapter s. Первый выбирает заказы для указанного клиента. Второй должен выбрать информацию о заказе заказов указанного клиента (которые выбираются первым SqlDataAdapter). Но я не могу найти способ сделать это элегантно. Когда я добавляю отношения, я получаю сообщение об ошибке: "Это ограничение не может быть включено, поскольку не все значения имеют соответствующие родительские значения".

Я не хочу отключать создание ограничения при создании отношения, я также не хочу выбирать все строки второй таблицы. Есть ли правильный способ сделать это? Или единственный способ создать инструкцию SQL с помощью предложения fe 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
    Давайте посмотрим на код. Предположительно, каждая деталь заказа должна иметь родительский порядок, поэтому, если все данные верны, такие отношения будут работать. Применяются ли отношения к правильным столбцам, являются ли они ненулевыми и т. Д. И т. Д.?
  • 0
    @barrick barrick, конечно, у каждой детали заказа должен быть родительский заказ, но я выбираю только заказы указанного клиента, а не все заказы, что делает деталь выбора заказа без условия Where непригодной для использования.
Показать ещё 5 комментариев
Теги:
datatable
relationship
dataset
sqldataadapter

1 ответ

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;'

как значение для идентификатора клиента, которое я хочу найти, и когда оно добавлено в ваш запрос, оно становится тем, что вы действительно не хотите выполнять.

  • 0
    Да, спасибо, я знаю об этом, это не настоящий код, вы знаете :) В реальных задачах я использую SqlParameter s, если входные данные поступают от пользователя ... Я надеялся, что есть хороший способ выполнить этот вид задач, возможно, используя какие-то внутренние колеса dotNet, без всяких хлопот с почерком SQL ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню