Как вы фильтруете FillBy TableAdapter на основе двух таблиц? - PullRequest
2 голосов
/ 04 января 2009

Я использую VS2008 C # Express и базу данных Northwind в приложении Windows Form.

Я использовал перетаскивание, чтобы настроить привязку основных данных (я использовал Заказы и Детали заказов) для двух видов сетки данных. На данный момент все работает как положено. Чтобы не возвращать каждую строку в таблице, я хочу отфильтровать таблицу «Заказы» на основе фильтра для таблицы «Заказы» И также по полю в таблице «Сведения о заказах». В мастере настройки адаптера таблиц я использовал построитель запросов, чтобы добавить новый FillByMyFilter, который создал следующий запрос:

ВЫБРАТЬ Заказы. [ID заказа], Заказы. [Идентификатор клиента], Заказы. [Идентификатор сотрудника], Заказы. [Имя корабля], Заказы. [Адрес корабля], Заказы. [Город отправления], Заказы. [Отправка Область, край], Заказы. [Почтовый индекс отгрузки], Заказы. [Страна доставки], Заказы. [Доставка через], Заказы. [Дата заказа], Заказы. [Требуемая дата], Заказы. [Дата отгрузки], Orders.Freight ИЗ ЗАКАЗОВ ВНУТРЕННЕГО СОЕДИНЕНИЯ [Детали заказа] ON Заказы. [Код заказа] = [Детали заказа]. [Код заказа] ГДЕ (Заказы. [Название корабля] НРАВИТСЯ% ') И ([Детали заказа]. Количество <20) </p>

Я получил это, добавив обе таблицы, но не проверял ни одно из полей в таблице «Сведения о заказе», чтобы он возвращал только те столбцы, которые использовались в исходном запросе Fill. Я только пытаюсь отфильтровать DataSet в основной таблице на данный момент и не вернуть другое количество столбцов. Дочерние строки сведений о заказе по-прежнему должны работать как нефильтрованный набор результатов по умолчанию.

Теперь проблема: когда я нажимаю кнопку «Выполнить запрос», она работает нормально. Я получаю 53 строки из вышеуказанного запроса, а не 1078, используя заливку по умолчанию, созданную дизайнером. Он возвращает те же столбцы, что и исходный запрос заполнения. Однако, когда я пытаюсь запустить приложение, я получаю следующую ошибку ограничения:

"Не удалось включить ограничения. Одна или несколько строк содержат значения, нарушающие ненулевые, уникальные или ограничения внешнего ключа."

Что я делаю не так?

ОБНОВЛЕНИЕ: Я думаю, что получаю ошибку ограничения из-за ВНУТРЕННЕГО СОЕДИНЕНИЯ, созданного Мастером. Если я отредактирую запрос, чтобы использовать LEFT JOIN, мастер снова изменит его на INNER JOIN.

Мой вопрос по-прежнему заключается в том, как фильтровать записи в родительской таблице (заказы) на основе критериев из родительской и дочерней таблиц. Мой следующий тест - попытаться использовать сохраненный процесс, но хотел бы знать, используя только пользовательский метод TableAdapter FillBy.

С уважением,

Debug

Ответы [ 4 ]

2 голосов
/ 04 января 2009

Эта статья содержит несколько предложений по устранению неполадок, чтобы точно определить строку, вызывающую проблему:

DataSet hell - "Не удалось включить ограничения. Одна или несколько строк содержат значения ...."

1 голос
/ 06 января 2009

Спасибо всем, что отправили ответ. Вот как я это сделал с помощью мастера TableAdapter и набора данных Northwind.

1) Щелкните правой кнопкой мыши родительскую таблицу в конструкторе xsd, чтобы добавить или настроить запрос. 2) Нажимайте кнопку «Далее» в мастере, пока не увидите кнопку «Построитель запросов». Нажмите кнопку Query Builder, чтобы перейти в режим построения запросов. 3) Щелкните правой кнопкой мыши и добавьте дочернюю таблицу на панели дизайна. У вас должны быть обе таблицы и ограничение по умолчанию, связывающее их. 4) Щелкните столбец в дочерней таблице, которую вы хотите отфильтровать (этот флажок будет удален позже), чтобы добавить его на панель критериев, чтобы можно было отфильтровать его. 5) Добавьте фильтр для родительского и дочернего столбцов. В этом примере я отфильтровал название корабля как «A%» и количество заказа <20. </p>

Обратите внимание, что на этом этапе вы можете проверить свой запрос, нажав кнопку «Выполнить запрос». Используя Northwind DB для SQL 2008 Compact Edition, я получаю 53 строки. Если бы вы сохранили его в этот момент, он потерпел бы неудачу во время выполнения из-за дублирования первичных ключей в наборе результатов. Так что следующие несколько шагов избавят их.

6) На панели критериев снимите флажок столбца дочерней таблицы, который вы добавили ранее. Фильтр останется, и тот же столбец теперь не будет отмечен на панели дизайна. Если вы выполните запрос, у вас останется 53 строки, но без столбца дочерней таблицы. 7) Щелкните правой кнопкой мыши панель дизайна и добавьте «Группировать по». На этом этапе, когда вы выполняете этот запрос, у вас не должно быть дубликатов в идентификаторе заказа. Я получил ровно 29 строк. 8) Нажмите OK, а затем кнопку «Далее», пока вы не сохраните новый запрос FillBy. 9) Измените свой исходный код, чтобы использовать новый FillBy.

Когда я запустил приложение, я получил отфильтрованную родительскую таблицу с теми же 29 строками, которые вернула кнопка «Выполнить запрос». Дочерняя таблица работала как ожидалось и содержала как минимум одну дочернюю строку, содержащую количество <20. </p>

Для реальных приложений, я думаю, было бы лучше использовать хранимый процесс или LINQ. Но эта проблема заставила меня почесать голову, и поэтому я "привел ее в порядок" только потому, что это был вызов (по крайней мере, для меня).

1 голос
/ 06 января 2009

Если вы посмотрите в Orders.Designer.cs (догадываясь, как я работаю в VB), вы, скорее всего, увидите уникальное ограничение, определенное для Orders (для первичного ключа).

Я подозреваю, что проблема в том, что когда вы выполняете запрос, вы получаете один или несколько отдельных Ордеров, которые имеют> 1 OrderDetails.Quanity> 20 .... так, что Орден будет возвращен дважды в вашем наборе результатов, что нарушает первичный ключ.

Try: ВЫБЕРИТЕ * из заказов, где [Имя отправителя] НРАВИТСЯ '% независимо от% И ИД заказа в (выберите ИД заказа из OrderDetails, где количество <20) </p>

Это, вероятно, очень неэффективный способ сделать это, в оракуле вы бы использовали EXISTS () вместо IN (), но я не знаю эквивалент сервера sql.

0 голосов
/ 05 января 2009

Надеюсь, вы получили ответ, но если нет, подумайте.

Если в вашем наборе данных есть отношения DataTables Order и OrderDetail, то это работает как ограничение FK. Таким образом, в дочерней таблице (OrderDetail) не может быть записей, у которых нет соответствующей родительской записи (Order). Таким образом, может произойти следующее: когда вы обновляете таблицу Data OrderTable с помощью упомянутого выше запроса, в таблице OrderDetail все еще остаются дочерние строки, которые будут иметь ссылки на родительские записи (Order), которых больше не будет после обновления. Тем не менее, если вы обновляете таблицу данных заказа, вам также необходимо обновить таблицу данных OrderDetail или удалить связь между двумя таблицами данных.

Надеюсь, это поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...