Примеры использования dbFacade. (SELECT)
В цикле прошлых статей я рассказал, как работать с классом dbFacade. Сегодня же, мы рассмотрим реальные примеры. Как это все работает — не спрашивайте, а читайте предыдущие посты по данной теме.
Давайте предположим, что у нас есть две таблицы со следующей структурой:
Таблица Song
id INTEGER //код песни
name TEXT //название песни
cd_id INTEGER //код диска, к которому относится песня
Таблица CD
id INTEGER //код диска
title TEXT //название диска
publish DATETIME //дата публикации
И так, у нас есть компакт-диски (таблица CD) и список песен (таблица Song). Песни связываются с таблицей CD через поле cd_id, в котором указывается значение поля CD.id. Один диск может содержать несколько песен. Давайте построим запрос для выборки. Предположим, что у нас уже заполнены обе таблицы.
В этом и последующих примерах предполагается, что объект с именем db, уже инициализирован:
dbFacade db = new dbFacade();
Самый простой запрос:
//SELECT * FROM CD
DataTable dt = db.FetchAll("CD"); //вернет все записи со всеми существующими полями
Чуть сложнее:
//SELECT * FROM CD WHERE title LIKE '%jovy%'
DataTable dt = db.FetchAll("CD","title LIKE '%jovy%'"); //все записи, в поле title которых присутствует jovy
На самом деле метод FetchAll используется редко. Если у вас много полей, а получить необходимо лишь пару, то лучше использовать метод FetchByColumn:
//SELECT publish FROM CD WHERE title LIKE '%jovy%'
DataTable dt = db.FetchByColumn("CD", "publish", "title LIKE '%jovy%'"); //тоже самое, что и в предыдущем примере, только на выходе будет список колонок publish
Если посмотрите, какие параметры принимают методы FetchAll и FetchByColumn, то заметите ограничения. В них нельзя использовать связывание. Для простых и более сложных запросов можно использовать метод Execute, передавая ему объект класса Select. О Select, я писал ранее.
//тоже самое, как и в предыдущем примере
Select select = new Select();
select.From("CD");
select.Columns("publish");
select.Where("title LIKE '%jovy%'");
DataTable dt = db.Execute(select);
Здесь вам необходимо понять принцип создания. Предыдущий пример я чаще всего записываю в более сокращенной форме:
DataTable dt = db.Execute(new Select()
.From("CD")
.Columns("publish")
.Where("title LIKE '%jovy%'"));
Давайте рассмотрим связывание между таблицами. Задача — получить все песни, которые относятся к конкретному диску:
//SELECT Song.id, name FROM CD INNER JOIN Song ON CD.id = Song.cd_id WHERE CD.id = 1
Select select = new Select()
.From("CD")
.Columns("Song.id, name")
.Join("Song", "CD.id = Song.cd_id", SQLJoinTypes.INNER_JOIN) //внутреннее связывание
.Where("CD.id = 1");
DataTable dt = db.Execute(select);
У нас в таблице CD есть поле типа DATETIME. Если вы хотите сделать выборку с условием даты, то в SQLite вам придется передавать дату в формате YYYY-MM-DD. Это жутко неудобно для русскоязычных пользователей. Следующий пример решает эту проблему:
//задаем параметры для последующей передачи
ParametersCollection parameters = new ParametersCollection();
parameters.Add("@date", DateTime.Parse("1.1.2011"), DbType.DateTime);
Select select = new Select()
.From("CD")
.Columns("title, publish")
.Where("publish < @date")
.Order("publish DESC")
.Limit(10);
//получить первые 10 записей, дата публикации которых была ранее 1.01.2011
//отсортированных в обратном порядке
DataTable dt = db.Execute(select, parameters);
Параметров может быть сколько угодно и они могут быть какими-угодно.
Также нужно всегда помнить, Join вы можете нанизывать, добавляя все новые и новые, остальные же операторы перезаписываются:
Select select = new Select()
.From("CD")
.Join(...);
select.From("Song"); //изменится с CD на таблицу Song
select.Join(...); //добавляем еще одно связывание. Итого уже будет два связывания
string s = select.SelectCommand; //так вы всегда можете посмотреть на сформированный запрос
Свойство SelectCommand возвращает текущий сформированный запрос. Таким способом вы всегда можете создавать вложенные запросы. Пример из реальной программы:
Select select = new Select()
.From("Кадры_Состав_Должности")
.Columns("Код_отдела")
.Where(string.Format("Номер_карточки = {0} AND Назначение_дата = ({1})", cardNum,
new Select()
.From("Кадры_Состав_Должности")
.Columns("MAX(Назначение_дата)")
.Where(string.Format("Назначение_дата <= GETDATE() AND Номер_карточки = {0}", cardNum)).SelectCommand));
Как показывает практика более сложные запросы, где более одного вложения, трудно читаемы. В принципе, вас никто не заставляет использовать класс Select для построения сложного запроса. Разработчик сам решает использовать ли Select или передавать сразу сформированную строку запроса (в Execute можно сделать и так).
DataTable dt = db.Execute("SELECT * FROM CD");
Вы сами решает насколько глубоко вам необходимо использовать возможности класса dbFacade.
Как вы заметили, я всегда результат выборки получал в виде DataTable. Что же с ним дальше делать? Разбирать… Чаще всего для этого используется конструкция foreach:
DataTable dt = db.Execute("SELECT * FROM CD");
foreach (DataRow row in dt.Rows)
{
MessageBox.Show(row[1].ToString()); //следующая строка равносильна
MessageBox.Show(row["title"].ToString());
}
или
//grdMain - DataGridView
grdMain.DataSource = db.Execute("SELECT * FROM CD");
Для получения одной строки используется метод FetchOneRow, который также может принимать Select и, опционально, параметры. В результате вы получаете Dictionary
//формируем запрос
Select select = new Select()
.From("CD")
.Columns("title, publish")
.Join("Song", "Song.cd_id = CD.id", SQLJoinTypes.INNER_JOIN)
.Where("id = 1");
//выполняем
Dictionary<string, object> item = db.FetchOneRow(select);
//далее получаем значения
string title = item["title"].ToString();
DateTime date = DateTime.Parse(item["publish"].ToString());
С выборкой закончили. В следующей статье я расскажу об удалении, вставке и изменении. Свои вопросы оставляйте в комментариях.
Популярность: 8%
Если у вас возникли вопросы, вы можете оставить их в комментариях


спасибо большое, пользуюсь давно, очень удобно и просто.
скажите пж а как определить количество записей в таблице, чисто скул я знаю — select count ()
но как через вашу конструкцию?:
//ОПРЕДЕЛИМ СКОЛЬКО ЗАПИСЕЙ В БД
Select select = new Select()
.From(db)
.Columns(«avtor»)
.Where(«main_id = » + zm + » «);
Очень просто:
В вашем примере
Select select = new Select()
.Columns(«count(avtor) as c»)
.From(db)
.Columns(«avtor»);
int count = int.Parse(db.FetchOneRow(select)["c"].ToString());
Это в самом простом варианте.
спасибо, проканало