Кастомный SqlQuery полезен в тех случаях, когда необходима предварительная обработка данных, которую проще реализовать на C#, и не нужно передавать клиенту лишние данные, используемые в обработке.
Для создания кастомных SqlQuery достаточно подключения основной библиотеки WorkflowEngine.dll.
Описание запроса
Пример синтаксиса кастомного запроса
<SqlQueryName="CustomSqlQuery"Type="CustomSqlQuery"Assembly="TemplateEngine"> <Text> SELECT null AS "Field0", null AS "Field1", null AS "Field2" LIMIT 0; </Text> <MySqlQuery> <Text> SELECT city.city_id AS "CityId", city.title AS "Title", city.archive AS "Archive" FROM template.city ORDER BY city.title; </Text> </MySqlQuery></SqlQuery>
В тэге <Text> можно указать запрос, который будет описывать поля ответа, доступные на форме, и не будет содержать записей. Такая договоренность позволяет понять структуру ответа без необходимости открывать исходный код элемента.
Тэг <MySqlQuery> является вспомогательным для получения данных, которые необходимо предварительно обработать. Таких тэгов может быть несколько - все зависит от задачи.
Обращение к запросу
Обращение к кастомному SqlQuery на форме ничем не отличается от обращения к платформенным SqlQuery:
Так же указываем поля таблицы, которую сервер возвращает клиентской части.
Исходный код
CustomSqlQuery.cs
usingSystem;usingSystem.Data;usingSystem.Collections.Generic;usingSystem.Threading.Tasks;usingMicrosoft.Extensions.DependencyInjection;usingCommon;namespaceWorkflowEngine{publicclassCustomSqlQuery:AbstractSqlQuery {privateconststring TEXT_ELEMENT ="Text";privateconststring MY_SQL_QUERY ="MySqlQuery";privatestring _mySqlQueryText;privatereadonlyISqlQueryHelper _sqlQueryHelper;publicCustomSqlQuery(IServiceProvider serviceProvider) : base(serviceProvider) { // Объект для замены переменных в тексте запроса _sqlQueryHelper =serviceProvider.GetService<ISqlQueryHelper>(); }publicoverridevoidInit(System.Xml.XmlNode node) { // В методе базового класса разбирается тэг <Text>, значение которого можно получить через переменную sqlQueryText
base.Init(node); // Получаем значение из тэга <Text>, вложенного в тэг <MySqlQuery> _mySqlQueryText =XmlParser.GetRequiredElementValue<string>( node,$"{MY_SQL_QUERY}/{TEXT_ELEMENT}", Name,this); } public async override Task<DataTable> Execute(IDatabaseConnection connection, Dictionary<string, object> parameters)
{ // Выполнение текста запроса из sqlQueryText, предварительно заменив переменный в тексте на значения параметров
var result =awaitconnection.ExecuteQueryAsync(GetQueryText(parameters)).ConfigureAwait(false); // Выполнение текста дополнительного запрос, предварительно заменив переменный в тексте на значения параметров
var myTable = await connection.ExecuteQueryAsync(_sqlQueryHelper.GetQueryText(_mySqlQueryText, parameters));
// Здесь будет код по обработке данных из запросов и формированию итоговой таблицы/* foreach (DataRow dataRow in myTable.Rows) { var newRow = result.NewRow(); newRow["Field0"] = ...; newRow["Field1"] = ...; newRow["Field2"] = ...; result.Rows.Add(newRow); } */return result; } }}
В конструкторе CustomSqlQuery используется метод GetService объекта типа ServiceProvider для получения объекта типа ISqlQueryHelper, который помогает построить текст запроса, заменив в нем переменные в круглых скобках {} на нужные значения:
В методе Init описывается парсинг xml-кода, для получение данных из серверного xml-файла. Статический метод GetRequiredElementValue класса XmlParser используется для получения значения обязательного тэга, путь до которого указывается в параметре string path. В качестве результата метод вернет строку. Если элемент отсутствует, будет возвращено исключение типа InvalidXmlException. Если необходимо получить значение необязательного элемента, то следует использовать метод GetElementValue. Этот метод в случае отсутствия элемента будет возвращать значение по умолчанию, переданное в параметрах метода.
В методе Execute описывается логика кастомного запроса, прописываются команды на выполнение запросов к базе данных и формируется объект типа DataTable, который будет отправляться в качестве ответа на клиентскую часть.
Для выполнения SQL-запросов используется метод ExecuteQueryAsync у объекта типа IDatabaseConnection, результатом которого будет объект типа DataTable: