В прошлой статье мы коснулись темы задание фильтра для получения объекта DataView на основе некоторого DataTable. Продолжая данную тему, в этой статье больше сосредоточимся на создании строки запроса для метода DataTable.Select(). Ведь, выполнять поиск возможно и по самому объекту DataTable, только в этом случае мы получим не конкретно объект DataView, а массив DataRow.

Итак. Имеем представленную выше схему взаимосвязанных таблиц в представлении строго типизированного DataSet.
Информация о книгах содержится в трех связанных таблицах. При чем, конкретно в таблице Books содержится всего единственное личное поле ISBN, а вся остальная информация о книге раcполагается в таблицах Authors (содержит имя автора книги) и Items (содержит название книги, издателя и дату издания).
Клиентский тип, представляющий книгу представлен классом:
class Book
{
String Name {get; private set;}
String Publisher {get; private set;}
DateTime PublishedDate {get; private set;}
String AuthorName {get; private set;}
String ISBN {get; private set;}
Public Book(string name, string publisher,
DataTime publishedDate, string authorName, string isbn)
{
Name = name;
Publisher = publisher;
PublishedDate = publishedDate;
AuthorName = authorName;
ISBN = isbn;
}
}
Возможный пользовательский интерфейс для выполнения поиска по книгам:

Мы можем задать название книги (поле Name), издателя (поле Publisher), дату издания (поле PublishedDate) и имя автора (поле AuthorName).
При нажатии на кнопку "Refresh" вызывается обработчик события Refresh_btn_Click:
Refresh_btn_Click(object sender, EventArgs e)
{
Book myBook = new Book(name_txbx.Text, publisher_txbx.Text,
publishedDate_txbx.Text, author_txbx.Text, null);
MyDataGridView.DataSource = GetSearchedBooks(myBook);
}
Метод GetSearchedBooks:
public List<Book> GetSearchedBooks(Book book)
{
string filter =
"Parent(FK_Books_Items).Name " +
"Like '%" + book.Name + "%' AND " +
"Parent(FK_Books_Authors).Name Like '%" +
book.AuthorName + "%' AND " +
"Parent(FK_Books_Items).Publisher Like '%" +
+book.Publisher + "%' AND " +
"Convert(Parent(FK_Books_Items)" +
".PublishedDate, 'System.String') " +
"Like '%" + book.PublishedDate + "%'";
DataRow[] searchedBooks =
bookDataSet.Books.Select(filter);
if(searchedBooks == null)
return null;
List<Book> books = new List<Book>();
foreach (DataRow searchedBook in searchedBooks)
{
books.Add(
new Book(searchedBook.
GetParentRow("FK_Books_Items")
["Name"].ToString(),
searchedBook.
GetParentRow("FK_Books_Items")
["Publisher"].ToString(),
searchedBook.
GetParentRow("FK_Books_Items")
["PublishedDate"].ToString(),
searchedBook["ISBN"].ToString(),
searchedBook.
GetParentRow("FK_Books_Authors")
["Name"].ToString()));
}
return books;
}
В данной статье самым интересным и есть метод GetSearchedBooks.
Разберем сперва строку фильтра:
string filter =
"Parent(FK_Books_Items).Name Like '%" +
book.Name + "%' AND Parent(FK_Books_Authors)" +
".Name Like '%" + book.AuthorName + "%'" +
" AND Parent(FK_Books_Items).Publisher Like '%" +
book.Publisher + "%' AND " +
"Convert(Parent(FK_Books_Items).PublishedDate," +
"'System.String') Like '%" +book.PublishedDate+ "%'";
Доступ к названию книги выполняется с помощью конструкции Parent(FK_Books_Items).Name – используем метод Parent с указанием имени связи. Так мы получили родительскую таблицу Items. А .Name получили значение поля Name.
Аналогично получаем значения полей из связанной родительской таблицы Authors:
Parent(FK_Books_Authors).Name.
Относительно сравнения даты издания, то тут мы применили конвертацию типов с помощью функции Convert:
Convert(Parent(FK_Books_Items).PublishedDate, 'System.String').
При создании объекта Book мы также воспользовались именами связей между таблицами для доступа к значениям соответствующих полей родительских таблиц через метод GetParentRow:
books.Add(
new Book(searchedBook.GetParentRow("FK_Books_Items")
["Name"].ToString(),
searchedBook.GetParentRow("FK_Books_Items")
["Publisher"].ToString(),
searchedBook.GetParentRow("FK_Books_Items")
["PublishedDate"].ToString(),
searchedBook["ISBN"].ToString(),
searchedBook.GetParentRow("FK_Books_Authors")
["Name"].ToString())
);
Соответственно, для доступа к дочерним таблицам используется метод GetChildeRow, или GetChildeRows.
Методы GetParentRow и GetParentRows возвращают одну запись из родительской таблицы и массив записей соответственно в зависимости от типа внешней связи (один к одному/один ко многим). То же справедливо по отношению методов GetChildeRow и GetChildeRows.
Также, если мы хотим выполнять метод Select для таблицы с учетом значений в дочерних таблицах, то для доступа к полям дочерней таблицы следует использовать функцию Child:
string filter =
"Child(FK_Books_Items).ISBN Like '%" + book.ISBN +
"%' AND Name Like '%" + book.Name + "%'";
DataRow[] searchedBooks = bookDataSet.Items.Select(filter);
Уверен, после данных разъяснений многие ваши запросы на поиск примут гораздо меньший объем кода и более эффектный вид.