Eloquera III

краткое описание / немного истории / установка / режимы работы базы: service, inmemory, desktop / восстановление базы
конфигурация / программная конфигурация / простейшие операции CRUD / insert / update / refreshMode / delete
построение запросов / joins / параметры / массивы / шаблонные контейнеры / order by / доступные функции / almos

Построение запросов

Eloquera позволяет писать запросы к базе данных на привычном многим SQL, причем с приятными дополнениями, которые я не встречал в MS SQL. Запросы можно писать в отношении полей и свойств класса, к дочерним объектам, коллекциям и массивам объектов. Все вместе это дает очень мощную платформу для анализа данных.

Как вы уже могли заметить, получение данных происходит с помощью двух функций:

  • ExecuteQuery(string query)
  • ExecuteScalar(string query)

Обе функции имеют перегруженные варианты для возможности указания глубины запрашиваемых объектов, параметров.  Да-да, можно строить параметризированные запросы.

Общий вид и порядок служебных слов в запросе тот же, что и в «обычном» SQL . Если делается запрос к одной сущности, то слово from можно опустить. Например:

Eloquera поддерживает операторы TOP, SKIP, Order by (подробно будет чуть позже).

Запросы можно строить не только для собственных полей класса, но и обращаться к составным полям, массивам. Сложный объект может содержать другие объекты или массивы, например:

Для доступа к полям других классов используйте точку после указания имени интересующей переменной.

«Глубину» — количество связанных объектов, можно так же ограничить во время запроса. Для этого используются перегруженные варианты методов ExecuteQuery или ExecuteScalar. Для получения всех объектов используйте методы без указания глубины, либо укажите значение параметра равное -1.

Важно!

При указании класса в запросе помните о case-sensitive природе C#, имя класса надо писать так, как оно объявлено в коде.

JOINs

Оператор JOIN впервые появился и был одобрен в стандарте SQL/92 и заменил собой оператор «+», который вызывал смущение в умах и являл собой пример непоследовательности в SQL/86. Назначением JOIN в реляционных базах данных является объединение результатов нескольких таблиц в виде одной. Для объектных баз данных полезность этого оператора может показаться сомнительной, так как объекты естественным для себя образом связанны с помощью ссылок. Однако, несмотря на это, оператор JOIN может послужить хорошим подспорьем в некоторых ситуациях.

Общий синтаксис операции:

Если при построении запроса с использованием  JOIN в SELECT были использованы два разных типа  или больше, то результатом такой операции будет новый объект IEnumerable<Dictionary<string, object>>. Если в человеческих словах, то это будет коллекция вида «имя типа — значение». При использовании в запросе только одного типа данных получим вырожденный вариант — простой массив.

JOIN запросы, так же как и другие типы запросов, могут использовать именованные параметры. В том числе в выражении ON. Однако следует помнить о некоторых ограничениях:

  • Значение параметра должно быть определено до того как начнется выполнение запроса.
  • Именованные параметры не могут быть использованы для замены имен типов в выражении Select. Т.е. попытка  вызвать Select @type будет вне правил.

Отдельно стоит упомянуть о том, как решается вопрос с наследниками классов, участвующих в построении выражения JOIN. Стандартным поведением считается возможность использования наследованных типов в запросе. Например, если TypeC  унаследован от  TypeA , тогда выражение:

может вернуть объекты типа TypeC в поле «а», если они удовлетворяют условиям выражения. Для того чтобы избавиться от всех потомков класса в результатах запроса, следует использовать слово ONLY. Т.е. переписать запрос вот так:

Теперь в поле «а» будут только объекты типа TypeA.

Пример в картинках на работу Inner Join. Пусть у нас есть такая структура данных:

Перед нами стоит задача найти все школы и рабочие места, находящиеся в одном месте. Запрос:

Код:

Результаты в виде таблицы можно представить так:

#

queryResult[“sch”]

queryResult[“wp”]

1

School1

wPlace2

2

School2

wPlace2

3

School3

wPlace3

4

School3

wPlace4

 

Параметры

В реальной жизни большинство запросов требуют параметризации, указания значений для фильтрации, чтобы сузить выборку, получить более конкретные результаты. Eloquera в полной мере поддерживает параметры для запросов, а грядущая 4я версия грозится порадовать нас хранимыми процедурами. Параметры могут быть любого типа.

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

Использовать параметры очень просто:

 

Для использования параметра в запросе, надо использовать перегруженный метод, который их принимает. Например:

В примере выше был использован параметр простого типа, однако параметры могут быть так же произвольного типа:

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

Массив значений параметра, может трактоваться базой как простой массив:

Параметры могут быть использованы с Top, Skip и Order By. Так же параметры могут содержать null.

Работа с массивами

Eloquera поддерживает различные типы массивов – многомерные, составные, простые. Примеры поддерживаемых массивов:

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

Доступ к полям элементов из массива осуществляется через точку.

К массивам применимы следующие операции: Contains, All, Any, In, Min, Max, Average, Median, Sum, Len. Массивы считаются равными только тогда, когда они совпадают поэлементно, при этом порядок не учитывается.

Работа с шаблонными контейнерами

База данных пытается сделать все поля доступными для поиска, даже приватные свойства класса доступны для этого. Именно поэтому способ, описанный ниже, стал возможен. В примере поиск идет с помощью внутреннего свойства коллекции List<>  — _items:

Order By

При построении запросов можно указать на необходимость сортировки результатов. Общий синтаксис построения выражения выглядит следующим образом:

По умолчанию применяется сортировка по возрастанию.

К примеру, в следующем выражении идет сортировка по имени и потом по дате рождения:

Сортировка может производиться и по более сложным условиям с использованием параметров:

В первом случае сначала показываются объекты, для которых значение выражения Interests in @interest  является истиной. Во втором случае используется составной объект.

Доступные функции

При написании запросов можно пользоваться полным спектром унарных операций:

Поддерживаются бинарные побитовые операции для целочисленных параметров:

  • X>>Y – сдвиг вправо
  • X<<Y  – сдвиг влево
  • ~X –  дополнение
  • X&Y –  логическое И
  • X|Y – логическое ИЛИ
  • X^Y – логический XOR

Поддержка логических операций: OR, AND, XOR. А так же операций сравнения: <, >, >=, <=, !=, =

Математические функции представлены следующим набором: Abs(x), Arccos(x), Arcctn(x), Arcsin(x), Arctan(x), Cos(x), Csec(x), Ctn(x), Exp(x), Ln(x), Log2(x), Log10(x), Max(x,y), Min(x,y), Power(x,y), Sec(x), Sin(x), Sqr(x), Sqrt(x), Tan(x).

Кроме того, можно использовать математические константы:

  • PI (pi = 3.14159…)
  • E (e = 2.71828…)

Функции для работы с датами:

  • AddDate(date, years, months, days),
  • AddTime(date, hours, minutes, seconds, milliseconds),
  • SubDate (date, years, months, days),
  • SubTime(date, hours, minutes, seconds, milliseconds),

Названия сами описывают свое назначение. И, как вы и подумали, не случиться ничего страшного, если в AddDate передать отрицательные значения, т.е. фактически функция превратиться в SubDate.

Для работы со строками в арсенале Eloquera есть следующие функции:

  • StrLen(x) – длина строки
  • SubString(x, offset, length) – подстрока с позиции offset длины length
  • ToLower(x) – все буквы строчные
  • ToUpper(x) –все буквы прописные
  • Trim(x) – обрезание пробелов у строки с двух сторон
  • X Contains Y – возвращает все Х которые содержат Y

При построении запроса есть возможность использования регулярных выражений.

  • X [NOT] LIKE Y – Возвращает True, если в X входит строка Y. Есть 2 служебных символа:

0    _ (подчеркивание) – заменяет собой один любой символ или пустоту

0    % (процент) – любая последовательность символов или пустота

  • X REGEX Y – Возвращает True, если X соответствует паттерну Y
  • X [NOT] IN (A, B, C) – аргументы могут быть любого типа. Возвращает True если X [не] принадлежит перечислению A, B, C
  • X [NOT] BETWEEN A AND B – аргументы могут быть численные или строковые, так же применимо к датам.

Almost

Особенно стоит остановиться на операторе ALMOST. Общий синтаксис выглядит так: x ALMOST [LIKE] y [WITHIN z].

X,Y –строка или число, z – число задающее расстояние Левенштейна между строками.

Функция возвращает True, если X попадает в указанный диапазон. Например, расстояние Левенштейна между «kitten» и «sitting» равняется 3, так как требуется 3 последовательных изменения по одному символу и за меньшее количество изменений это сделать невозможно.

  1. kitten > sitten (‘s’ меняется на ‘k’)
  2. sitten > sittin (‘i’ меняется на ‘e’)
  3. sittin > sitting (вставляем ‘g’ в конец строки).

Расстояние между числами измеряется как abs(x-y)

Продолжение следует…

Hard’n’heavy!

Оставить комментарий