1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/dotnetlowcode-hisql

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

HiSql

В настоящее время ORM-фреймворк основан на сущностях, что вызывает определённые трудности при изменении или добавлении полей. Поэтому возникла идея разработки бессущностного ORM. HiSql решает эту проблему и позволяет работать с данными в соответствии с болевыми точками проекта. Это первый ORM-фреймворк, поддерживающий Hana, и он поддерживает распространённые базы данных.

Особенности

  1. Поддержка бессущностных данных (нет необходимости создавать классы сущностей).
  2. Динамическое обнаружение данных (предварительное сопоставление типов, длины и структуры таблицы).
  3. Синтаксис, близкий к исходному SQL.
  4. Мониторинг тайм-аута (например, запись выполнения SQL-запросов, которые занимают более 5 секунд).
  5. Поддержка различных библиотек с возможностью самостоятельного выбора необходимых.

Проектные ссылки

Можно установить через NuGet.

  1. Ссылка на файл HiSql.dll.
  2. В зависимости от потребностей базы данных можно ссылаться на SDK для реализации баз данных:
    • HiSql.sqlserver.dll;
    • HiSql.hana.dll;
    • HiSql.mysql.dll;
    • HiSql.oracle.dll;
    • HiSql.postgresql.dll;
    • HiSql.dameng.dll (поддерживается начиная с версии 1.0.4);
    • HiSql.Sqlite.dll (поддержка добавлена в версии 1.0.4.7).

Официальная группа HiSql

Чтобы лучше обслуживать реальных пользователей HiSql, участники группы должны быть либо на GitHub, либо на Gitee, где они поставили звёздочку проекту HiSql или сделали пожертвование.

Начальная установка

Примечание: необходимо выполнить только один раз.

sqlclient.CodeFirst.InstallHisql();

Популярные ORM-фреймворки требуют динамического составления запросов, но это возможно только с использованием исходного SQL. HiSql предлагает новый синтаксис, который может выполняться в разных базах данных.

Основным недостатком традиционных ORM-фреймворков является их полная зависимость от сущностей и использование лямбда-выражений для написания запросов. Однако основная проблема заключается в том, что при необходимости динамического объединения условий приходится переключаться на исходный SQL. Разработчики также должны решать проблемы с инъекциями. HiSql эффективно решает эти проблемы, обрабатывая инъекции на уровне базы данных, позволяя разработчикам сосредоточиться на бизнес-логике.

Обновление от 16.04.2024

  1. Исправлены ошибки SQLite.

Обновление 1.0.6.1 от 13.11.2023

  1. Исправлено ограничение длины при использовании % в запросах с подстановочными знаками.
  2. Исправлена проблема с получением описания структуры представления (если описание поля было изменено вручную, будет использоваться Hi_FieldModel).

Оптимизация синтаксиса HiSql от 2023.06.12

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

var _sql = sqlClient.HiSql("select a.tabname from Hi_TabModel as a where a.tabname in (select b.tabname from Hi_FieldModel as b where b.tabname = `a.tabname`)").ToSql();

Исправление ошибок update от 30.05.2023

Версия 1.0.5.9: исправлена ошибка в определённых сценариях при генерации запросов на обновление.

Параметризация оптимизирована от 18.04.2023

Пример использования:

var _paramsql = sqlClient.HiSql(@"select * from Hi_FieldModel where tabname in (@TabName)  and fieldname=@fieldname and tabname in (select tabname from hi_tabmodel where tabname in (@TabName))", new { TabName = new List<string> { "Hi_TestQuery", "Hi_FieldModel" }, FieldName = "DbServer" }).ToSql();
Console.WriteLine(_paramsql);

Обновления от 11.04.2023

  1. Решена проблема, когда при первом получении информации о таблице в многопоточной среде возникала ошибка таблицы.
  2. Решены проблемы с преобразованием типов данных в SQL Server, связанные с типами varchar|nvarchar|(max), которые вызывали исключения при переходе на HANA и другие базы данных.
  3. Для таблиц HANA, содержащих поля типа [TEXT], используйте метод Modi для обработки ошибок, связанных с временными таблицами HANA, не поддерживающими тип text.

Оптимизация транзакций Если требуется использовать несколько таблиц и выполнять несколько действий по обновлению, рекомендуется использовать следующий подход для предотвращения взаимоблокировок.

void transDemo(HiSqlClient sqlClient)
{
    int count = 10;
    string tabname = typeof(H_Test02).Name;
    List<object> lstdata = buildData10Col(count);

    sqlClient.Delete(tabname).ExecCommand();

    using (var sqlClt = sqlClient.CreateUnitOfWork())
    { 
        sqlClt.Insert(tabname, lstdata).ExecCommand();

        sqlClt.Modi(tabname, lstdata).ExecCommand();
        sqlClt.CommitTran();
        //sqlClt.RollBackTran();
    }


}

Обновления от 25.03.2023

  1. Полная поддержка HiSql для .NET 7.0.

  2. Значение bool по умолчанию изменено на false.

  3. Добавлена возможность экспорта данных в Excel с поддержкой изображений. Текст запроса написан на языке C#.

  4. hisql нижний уровень автоматически будет нумеровать согласно конфигурации snro:

    list.Add(new { uname =$"uname{i}",age=20i,descript=$"test{i}"});*

}

sqlClient.Insert("H_Test5", list).ExecCommand();

  1. Посмотреть результат:

  1. 2022.6.21 Добавлена параметризация запросов hisql:

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

string sql1= sqlClient.HiSql("select * from hi_tabmodel where tabname=@tabname ", new { TabName="H_test" ,FieldName="DID"}).ToSql();
string sql2= sqlClient.HiSql("select * from hi_tabmodel where tabname=@tabname or TabType in( @TabType)", new { TabName="H_test" , TabType =new List<int> { 1,2,3,4} }).ToSql();

string sql3 = sqlClient.HiSql("select * from hi_tabmodel where tabname=@tabname ", new Dictionary<string, object> { { "TabName", "H_test" } }).ToSql();

Также поддерживается предыдущая версия написания параметров (но не рекомендуется использовать, возможно, в будущем она будет удалена):

string sql4 = sqlClient.HiSql("select * from hi_tabmodel where tabname=[$tabname$] ", new Dictionary<string, object> { { "[$tabname$]", "H_test" } }).ToSql();
  1. 2022.6.21 Добавлен режим рабочей единицы:

CreateUnitOfWork по умолчанию начинает транзакцию, после завершения работы в рабочей единице транзакция будет автоматически зафиксирована, если требуется выполнить откат, используйте RollBackTran для отката транзакции.

using (var client = sqlClient.CreateUnitOfWork())
{
    client.Insert("H_UType", new { UTYP = "U4", UTypeName = "高级用户" }).ExecCommand();

    //client.RollBackTran();
    

}
  1. 2022.6.15 Добавлена поддержка базы данных dameng:

  2. Добавлена поддержка dameng базы данных. В настоящее время hisql уже поддерживает sqlserver,hana,mysql,oracle,posgresql,dameng шесть типов баз данных, включая международные, отечественные и столбцовые хранилища. Следующим шагом будет поддержка sqlite.

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

  4. Добавлен метод ToColumns() для возврата структуры информации о результатах запроса hisql.

Эту функцию можно использовать для сохранения результатов запроса в новой таблице (можно создать новую таблицу на основе этой структуры полей).

//возвращает структуру информации о результате этого запроса hisql
List<HiColumn> cols = sqlClient.HiSql("select max(FieldType) as fieldtype from Hi_FieldModel").ToColumns();
  1. 2022.6.11 Добавлены шаблоны запросов:

Используйте `` для обозначения поля. Если это числовой тип, то поддерживаются выражения.

string sql = sqlClient.HiSql("select * from Hi_FieldModel as a where a.TabName=`a.TabName` and a.FieldName='11'").ToSql();

Пример выражения шаблона:

string sql = sqlClient.HiSql("select * from Hi_FieldModel as a where a.SortNum=`a.SortNum`+1 and a.FieldName='11'").ToSql();

Ниже приведён пример синтаксиса цепного запроса:

string sql = sqlClient.Query("Hi_FieldModel", "A").Field("*")
    .Where(new Filter {
        {"A.TabName", OperType.EQ, "`A.FieldName`"}
                     })
    .Group(new GroupBy { { "A.FieldName" } }).ToSql();

Пример синтаксиса выражения шаблона:

string sql = sqlClient.Query("Hi_FieldModel", "A").Field("*")
    .Where(new Filter {
        {"A.SortNum", OperType.EQ, "`A.SortNum`+1"}
                     })
    .Group(new GroupBy { { "A.FieldName" } }).ToSql();
  1. 2022.6.10 Добавлен синтаксис on:

Исходный синтаксис соединения on допускает только равенство полей, теперь он также поддерживает условия, подобные where.

var sql = sqlClient.HiSql("select a.TabName, a.FieldName from Hi_FieldModel as a left join Hi_TabModel as b on a.TabName=b.TabName and a.TabName in ('H_Test') where a.TabName=b.TabName and a.FieldType>3 ").ToSql();
  1. 2022.6.7 Решена проблема с набором символов в mysql:

При использовании HiSql в старых версиях mysql возникает следующая ошибка:

One or more errors occurred.(Unknow collation:'utf8mb4_0900_ai_ci')

Спасибо автору freesql за сообщение об ошибке.

  1. 2022.6.1 Генерация номеров:

В обычном бизнесе часто требуется генерировать уникальные номера в соответствии с различными правилами в качестве первичного ключа таблицы или генерировать идентификаторы снежинки. HiSql предоставляет функцию генерации номеров, которая поддерживает распределённую уникальную генерацию номеров.

Для получения подробной информации см. подробное руководство по номерам hisql.

Вот как это работает:

  1. Конфигурация:
Global.SnroOn = true;//указывает, что функция генерации номеров включена
sqlClient.CodeFirst.InstallHisql();//включает и инициализирует установку, автоматически создаст таблицу Hi_Snro во время установки


//добавляем конфигурацию генерации номеров
//SNRO представляет основное имя номера SNUM представляет идентификатор субномера
var obj1 = new { SNRO = "MATDOC", SNUM = 1, IsSnow=false, SnowTick=0, StartNum = "9000000", EndNum = "9999999",Length=7, CurrNum = "9000000", IsNumber = true, IsHasPre = false, CacheSpace = 10, Descript = "материальный основной номер данных" };


//добавить конфигурацию идентификатора снежинки
//SNRO представляет основное имя номера SNUM представляет идентификатор субномера
var obj2 = new { SNRO = "Order", SNUM = 1, IsSnow=true, SnowTick=145444, StartNum = "", EndNum = "",Length=7, CurrNum = "", IsNumber = true, IsHasPre = false, CacheSpace = 10, Descript = "номер заказа идентификатор снежинки" };

List<object> list = new List<object>();
list.Add(obj1);
list.Add(obj2);

sqlClient.Modi("Hi_Snro", list).ExecCommand();
  1. Использование номеров:
public static SeriNumber number = null;  //определяем глобальную переменную для изменения номера
  1. Установите соединение номера:
//sqlClient — это объект подключения к базе данных

``` **Текст запроса:**

Extension.TempType.STANDARD, DataBeginRow = 2, HeaderRow = 1 });
DataTable dt = excel.ExcelToDataTable(@"D:\data\GD_UniqueCodeInfo2.xlsx", true);

Перевод:

Тип расширения. Временной тип. СТАНДАРТ, строка начала данных = 2, строка заголовка = 1.

Таблица данных dt = Excel. Метод ExcelToDataTable (путь к файлу @"D:\data\GD_UniqueCodeInfo2.xlsx", истина).

Примечание: в запросе присутствуют фрагменты кода на языке C#, которые не были переведены. 1. Console.WriteLine(rtn.Item3);//вывод таблицы с переименованными столбцами SQL } else Console.WriteLine(rtn.Item2);//вывод причины ошибки переименования.

2. Добавление поля в таблицу:

//OpLevel.Execute  — выполнение и возврат сгенерированного SQL
//OpLevel.Check — только проверка, сообщение о сбое возвращается при неудачной проверке, а при успешной проверке возвращается причина генерации SQL
HiColumn column = new HiColumn()
{
    TabName = "H_Test5",
    FieldName = "TestAdd",
    FieldType = HiType.VARCHAR,
    FieldLen = 50,
    DBDefault = HiTypeDBDefault.EMPTY,
    DefaultValue = "",
    FieldDesc = "Тестирование добавления поля"
};
var rtn= sqlClient.DbFirst.AddColumn("H_Test5", column, OpLevel.Execute);
if (rtn.Item1)
{
    Console.WriteLine(rtn.Item2);//сообщение об успешном выполнении
    Console.WriteLine(rtn.Item3);//сгенерированный SQL
}
else
    Console.WriteLine(rtn.Item2);//причина ошибки

3. Изменение поля в таблице:

//OpLevel.Execute — выполнение и возврат сгенерированного SQL
//OpLevel.Check — только проверка, сообщение о сбое возвращается при неудачной проверке, а при успешной проверке возвращается причина генерации SQL
HiColumn column = new HiColumn()
{
    TabName = "H_Test5",
    FieldName = "TestAdd",
    FieldType = HiType.VARCHAR,
    FieldLen = 51,
    DBDefault = HiTypeDBDefault.VALUE,
    DefaultValue = "TGM",
    FieldDesc = "Тестирование изменения поля"
};

var rtn = sqlClient.DbFirst.ModiColumn("H_Test5", column, OpLevel.Execute);
if (rtn.Item1)
{
    Console.WriteLine(rtn.Item2);//успешное выполнение
    Console.WriteLine(rtn.Item3);//сгенерированный SQL
}
else
    Console.WriteLine(rtn.Item2);//ошибка

4. Переименование поля в таблице:

//OpLevel.Execute — выполнение и возврат сгенерированного SQL
//OpLevel.Check — только проверка, сообщение о сбое возвращается при неудачной проверке, а при успешной проверке возвращается причина генерации SQL
HiColumn column = new HiColumn()
{
    TabName = "H_Test5",
    FieldName = "Testname3",
    ReFieldName = "Testname2",
    FieldType = HiType.VARCHAR,
    FieldLen = 50,
    DBDefault = HiTypeDBDefault.VALUE,
    DefaultValue = "TGM",
    FieldDesc = "Переименование поля для тестирования"
};

var rtn = sqlClient.DbFirst.ReColumn("H_Test5", column, OpLevel.Execute);
if (rtn.Item1)
{
    Console.WriteLine(rtn.Item2);//успешное выполнение
    Console.WriteLine(rtn.Item3);//сгенерированный SQL
}
else
    Console.WriteLine(rtn.Item2);//ошибка

5. Изменение поля в таблице (аналогично пункту 3):

//OpLevel.Execute — выполнение и возврат сгенерированного SQL
//OpLevel.Check — только проверка, сообщение о сбое возвращается при неудачной проверке, а при успешной проверке возвращается причина генерации SQL
HiColumn column = new HiColumn()
{
    TabName = "H_Test5",
    FieldName = "TestAdd",
    FieldType = HiType.VARCHAR,
    FieldLen = 51,
    DBDefault = HiTypeDBDefault.VALUE,
    DefaultValue = "TGM",
    FieldDesc = "Тестирование изменения поля"
};

var rtn = sqlClient.DbFirst.ModiColumn("H_Test5", column, OpLevel.Execute);
if (rtn.Item1)
{
    Console.WriteLine(rtn.Item2);//успешное выполнение
    Console.WriteLine(rtn.Item3);//сгенерированный SQL
}
else
    Console.WriteLine(rtn.Item2);//ошибка

6.

7. Синхронизация изменений структуры физической таблицы:

//OpLevel.Execute — выполнение и возврат сгенерированного SQL
//OpLevel.Check — только проверка, сообщение о сбое возвращается при неудачной проверке, а при успешной проверке возвращается причина генерации SQL
var tabinfo = sqlClient.Context.DMInitalize.GetTabStruct("H_Test5");

TabInfo _tabcopy = ClassExtensions.DeepCopy<TabInfo>(tabinfo);
_tabcopy.Columns[2].ReFieldName = "Testname3";
var rtn= sqlClient.DbFirst.ModiTable(_tabcopy, OpLevel.Execute);
if (rtn.Item1)
{
    Console.WriteLine(rtn.Item2);//успешное выполнение
    Console.WriteLine(rtn.Item3);//сгенерированный SQL
}
else
    Console.WriteLine(rtn.Item2);//ошибка

8. Получение списка таблиц и представлений текущей базы данных:

//Получение всех физических таблиц текущей базы данных
List<TableInfo> lsttales = sqlClient.DbFirst.GetAllTables();
foreach (TableInfo tableInfo in lsttales)
{
    Console.WriteLine($"{tableInfo.TabName} {tableInfo.TabReName} {tableInfo.TabDescript} {tableInfo.TableType} структура таблицы:{tableInfo.HasTabStruct}");
}

9. Получение глобальных временных таблиц текущей базы данных:

//Получение глобальных временных таблиц текущей базы данных
List<TableInfo> lsttales = sqlClient.DbFirst.GetGlobalTempTables();
foreach (TableInfo tableInfo in lsttales)
{
    Console.WriteLine($"{tableInfo.TabName} {tableInfo.TabReName} {tableInfo.TabDescript} {tableInfo.TableType} структура таблицы:{tableInfo.HasTabStruct}");
}

10. Создание представления на основе HiSql-запроса:

//OpLevel.Execute — выполнение и возврат сгенерированного SQL
//OpLevel.Check — только проверка, сообщение о сбое возвращается при неудачной проверке, а при успешной проверке возвращается причина генерации SQL
var rtn = sqlClient.DbFirst.CreateView("vw_FModel", 
sqlClient.HiSql("select a.TabName,b.TabReName,b.TabDescript,a.FieldName,a.SortNum,a.FieldType from Hi_FieldModel as a inner join Hi_TabModel as b on a.TabName=b.TabName").ToSql(), 
OpLevel.Execute);

if (rtn.Item1)
{
    Console.WriteLine(rtn.Item2);//успешное создание
    Console.WriteLine(rtn.Item3);//сгенерированный SQL
}
else
    Console.WriteLine(rtn.Item2);//ошибка создания

11. Удаление указанного представления:

//OpLevel.Execute — выполнение и возврат сгенерированного SQL
``` **Текст запроса:**

```c#
//在表中添加用户类型 Modi方法的意思是 如果存在则更新没有则插入
            sqlClient.Modi("H_UType", new List<object> {
                new { UTYP = "U1", UTypeName = "普通用户" },
                new { UTYP = "U2", UTypeName = "中级用户" },
                new { UTYP = "U3", UTypeName = "高级用户" }
            }).ExecCommand();

// 增加表校验配置
sqlClient.Update("Hi_FieldModel", new { TabName = "HTest01", FieldName = "UTYP", IsRefTab=true,RefTab= "H_UType",RefField="UTYP", RefFields = "UTYP,UTypeName",RefFieldDesc= "类型编码,类型名称",RefWhere="UTYP<>''" }).ExecCommand();

//执行数据插入
sqlClient.Insert("HTest01", new { SID = "0", UTYP = "U4", UName = "hisql", Age = 36, Salary = 11, Descript = "hisql" }).ExecCommand();

Перевод текста на русский язык:

//В таблице добавляем пользовательский тип. Метод Modi означает, что если он существует, то он обновляется, а если нет — вставляется. sqlClient.Modi («H_UType», новый список<объект> { новый { UTYP = «U1», UTypeName = «обычный пользователь» }, новый { UTYP = «U2», UTypeName = «пользователь среднего уровня» }, новый { UTYP = «U3», UTypeName = «опытный пользователь» } }). ExecCommand ();

// Добавляем конфигурацию проверки таблицы sqlClient.Update («Hi_FieldModel», новый { TabName = «HTest01», FieldName = «UTYP», IsRefTab = true, RefTab = «H_UType», RefField = «UTYP», RefFields = «UTYP, UTypeName», RefFieldDesc = «код типа, имя типа», RefWhere = «UTYP <> » »»). ExecCommand ();

//Выполняем вставку данных sqlClient.Insert («HTest01», новый {SID = «0», UTYP = «U4», UName = «hisql», Age = 36, Salary = 11, Description = «hisql»}). ExecCommand (); Запрос 1:

.Where(new Filter { { "("}, {"A.TabName", OperType.EQ, "Hi_FieldModel"}, {"A.FieldName", OperType.EQ, "CreateName"}, { ")"}, { LogiType.OR}, { "("}, {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} }, { ")"} }) .Group(new GroupBy { { "A.FieldName" } }).ToSql();

Перевод:

Где (новый фильтр { { «(», «A.TabName», OperType.EQ, «Hi_FieldModel», «A.FieldName», OperType.EQ, «CreateName», {«)», LogiType.OR, {«(», «A.FieldType», OperType.BETWEEN, новый RangDefinition() {Low = 10, High = 99}, {«)»} }) Группировать по (новая группа {«A.FieldName»}). ToSql().

Запрос 2:

2.2 字符串写法如下所示
支持 字符串写法解决通过应用前端可以自定义传条件过来 `a.tabname = 'Hi_FieldModel' and ((a.FieldType = 11)) `
看这个语法类似于sqlserver的写法,与sqlserver无关, 这是Hisql自定义的中间语法 通过hisql编译后在hisql支持的库中运行

注:暂时不支持in,not in写法 下一版本将会加上


```c#
string jsondata = sqlClient.Query("Hi_FieldModel", "A").Field("A.FieldName as Fname")
    .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } })
    .Where("a.tabname = 'Hi_FieldModel' and ((a.FieldType = 11)) ")
    .Group(new GroupBy { { "A.FieldName" } }).ToJson();

Перевод:

2.2 Строка написана следующим образом: Поддерживает строковое написание, решая проблему с помощью приложения на переднем конце, можно настроить передачу условий a.tabname = 'Hi_FieldModel' и ((a.FieldType = 11)). Посмотрите на этот синтаксис, похожий на синтаксис SQL Server, не связанный с SQL Server, это промежуточный синтаксис Hisql, скомпилированный через hisql и работающий в библиотеках, поддерживаемых hisql.

Примечание: временно не поддерживает in, not in синтаксис. Будет добавлено в следующей версии.

Код на C#:

Строка jsonData = sqlClient.Запрос («Hi_FieldModel», «A»). Поле («A.FieldName как Fname») .Присоединиться («Hi_TabModel»). Как («B»). On (новое JoinOn { { «A.TabName», «B.TabName» } }) .Где («a.tabname = 'Hi_FieldModel' и ((a.FieldType = 11))») .Группировать (новая GroupBy { { «A.FieldName» } }). ToJson().

В запросе присутствуют фрагменты кода на языке C#, но они не содержат запросов или технических терминов, поэтому их перевод не требуется. UTYPE}).ToSql();


2. **Массовая вставка данных**

    Для работы с таблицами не нужно использовать сущности, как в других фреймворках. HiSql позволяет работать без сущностей, но если вы привыкли к ним, то можете их использовать.

    ```c#
    int _times = 100000;
    List<object> lstobj = new List<object>();
    for (int i = 0; i < _times; i++)
    {
        lstobj.Add(new { Domain = $"{i}", DomainDesc = $"用户类型{i}" });

    }
    sqlclient.Insert("Hi_Domain", new { Domain = "UTYPE", DomainDesc = "用户类型" }).ExecCommand();
    ```
---

3. **Обновление или вставка данных в зависимости от наличия записи**
   Часто в бизнес-разработке возникают ситуации, когда необходимо обновить данные, если запись существует, и вставить данные, если её нет. Обычно это делается с помощью хранимых процедур или отдельных SQL-запросов. Однако HiSql предоставляет более удобный способ:

   *Примечание: если первичный ключ таблицы является автоинкрементным идентификатором, то эта функция не будет работать.*

    ```c#
    //Если запись существует, она будет обновлена, иначе — вставлена. Поддерживает массовую операцию
     sqlClient.Modi("H_Test", new { Hid = 1, UserName = "tansar", UserAge = 100, ReName = "Tom" }).ExecCommand();



    ```
### Запрос данных из таблицы

1. **Запрос одной таблицы**
    
    Результаты запроса можно преобразовать в таблицу ToTable, в JSON ToJson, в список ToList или в динамический объект ToDynamic. В этом примере показано использование ToTable.
    1. Запрос возвращает DataTable. Здесь также используется сортировка.
        ```c#
        DataTable DT_RESULT1= sqlclient.Query("DataDomain").Field("Domain").Sort(new SortBy { { "createtime" } }).ToTable();
        ```

        Определение псевдонимов для таблицы.
        ```c#
        DataTable DT_RESULT2 = sqlclient.Query("DataDomain").As("a").Field("a.Domain").Sort(new SortBy { { "a.createtime" } }).ToTable();
        ```
    2. Запрос возвращает список объектов. В методе Field() передаётся "*", чтобы получить все поля таблицы.

        ```c#
        List<Hi_Domain> lstefresult = sqlclient.Query("Hi_Domain").Field("*").Sort("createtime asc", "moditime").ToList<Hi_Domain>();

        ```
    3. Запрос с использованием разбивки на страницы.
        ```c#
        DataTable DT_RESULT3 = sqlclient.Query("DataDomain").As("a").Field("a.Domain").Sort(new SortBy { { "a.createtime" } }).Skip(1).Take(100).ToTable();

        ```

2. **Простой запрос с объединением нескольких таблиц**

    1. Объединение двух таблиц и применение условий фильтрации и разбивки на страницы:
        ```c#
        DataTable DT_RESULT = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName as Fname")
                    .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } }) 
                    .Where(new Filter {
                        {"A.TabName", OperType.EQ, "Hi_FieldModel"},
                        {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} },
                    })
                    .Skip(1).Take(10).ToTable();
        ```
    2. Реализация запроса с группировкой group by:

        ```c#
        DataTable DT_RESULT = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName as Fname")
                .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } }) 
                .Where(new Filter {
                    {"A.TabName", OperType.EQ, "Hi_FieldModel"},
                    {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} },
                })
                .Group(new GroupBy { { "A.FieldName" } })
                .ToTable();
        ```
    3. Выполнение запроса с использованием статистических функций:

        ```c#
        DataTable dt_resultfun = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName    as    Fname", "count(*) as avgFieldLen")
                .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } })
                .Where(new Filter {
                    {"A.TabName", OperType.EQ, "Hi_FieldModel"},
                    {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} },

                })
                .Group(new GroupBy { { "A.FieldName" } })
                .ToTable();
        ```

        Поддерживаемые функции:

        - count  образец count(*) as scount
        - avg образец avg("score") as avgscore  *примечание:* score должно быть числовым значением, иначе HiSql выдаст ошибку
        - sum образец sum("score") as sumscore  *примечание:* score должно быть числовым значением, иначе HiSql выдаст ошибку
        - min образец min("score")  as minscore 
        - max образец max("score") as maxscore

    4. Объединение нескольких таблиц с применением разбивки на страницы:

        Можно выполнять разбивку на страницы для данных, полученных после объединения таблиц.
        ```c#
        DataTable dt_resultfun = sqlclient.Query("Hi_FieldModel", "A").Field("A.FieldName    as    Fname", "count(*) as avgFieldLen")
                .Join("Hi_TabModel").As("B").On(new JoinOn { { "A.TabName", "B.TabName" } })
                .Where(new Filter {
                    {"A.TabName", OperType.EQ, "Hi_FieldModel"},
                    {"A.FieldType",OperType.BETWEEN,new RangDefinition(){ Low=10,High=99} },

                })
                .Group(new GroupBy { { "A.FieldName" } })

``` 3. Сложный запрос с объединением подзапросов и использованием UNION ALL:

```c#
DataTable dt_resultuinon = sqlclient.Query(
    sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.IN,
        sqlclient.Query("Hi_TabModel").Field("TabName").Where(new Filter { {"TabName",OperType.IN,new List<string> { "Hone_Test", "H_TEST" } } })
    } }),
    sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "DataDomain" } }),
    sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "Hi_FieldModel" } })
)
    .Field("TabName", "count(*) as CHARG_COUNT")
    .Group(new GroupBy { { "TabName" } }).ToTable();
  1. Сложные запросы с группировкой и ранжированием результатов:

С помощью метода WithRank можно сортировать результаты запроса по рангу. DbRank.DENSERANK не пропускает номера при ранжировании, DbRank.RANK пропускает, а DbRank.ROWNUMBER сортирует по номеру строки.

DataTable dt_resultuinon = sqlclient.Query(
    sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.IN,
        sqlclient.Query("Hi_TabModel").Field("TabName").Where(new Filter { {"TabName",OperType.IN,new List<string> { "Hone_Test", "H_TEST" } } })
    } }),
    sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "DataDomain" } }),
    sqlclient.Query("Hi_FieldModel").Field("*").Where(new Filter { { "TabName", OperType.EQ, "Hi_FieldModel" } })
)
    .Field("TabName", "count(*) as CHARG_COUNT")
    .WithRank(DbRank.DENSERANK, DbFunction.NONE, "TabName", "rowidx1", SortType.ASC)
    .WithRank(DbRank.ROWNUMBER, DbFunction.COUNT, "*", "rowidx2", SortType.ASC)
    .WithRank(DbRank.RANK, DbFunction.COUNT, "*", "rowidx3", SortType.ASC)
    .Group(new GroupBy { { "TabName" } }).ToTable();
  1. Прямое подключение к базе данных для выполнения запросов:

Запрос с использованием IN:

DataTable dt= sqlClient.Context.DBO.GetDataTable("select * from dbo.Hi_FieldModel where TabName in (:TabName)", new HiParameter(":TabName",new List<string> { "Hi_TabModel", "Hi_FieldModel" }));

Запрос с использованием одного значения переменной:

DataTable dt = sqlClient.Context.DBO.GetDataTable("select * from dbo.Hi_FieldModel where TabName = @TabName", new HiParameter("@TabName", "Hi_TabModel"));
  1. Обновление данных в таблице:

Обновление без использования сущности:

int _effect = sqlClient.Update("H_TEST", new { DID = 1, UNAME = "UTYPE", UNAME2 = "user123" }).Exclude("UNAME").ExecCommand();

SQL-запрос:

update [dbo].[H_TEST] set [UNAME2]='user123' where [DID]=1

Обновление с использованием условия WHERE:

int _effect1 = sqlClient.Update("H_TEST").Set(new { UNAME2 = "TEST" }).Where(new Filter { { "DID", OperType.GT, 8 } }).ExecCommand();

SQL-запрос:

update [dbo].[H_TEST] set [UNAME2]='TEST' where [H_TEST].[DID] > 8

Использование сущности для обновления данных:

class H_Test
{ 
    public int DID {
        get;set;
    }
    public string UNAME {
        get;set;
    }
    public string UNAME2
    {
        get;set;
    }
}
int _effect2 = sqlClient.Update<H_Test>(new H_Test { DID = 1, UNAME2 = "Haha1" }).Only("UNAME2").ExecCommand();

SQL-запрос:

update [dbo].[H_Test] set [UNAME2]='Haha1' where [DID]=1

Пакетное обновление:

int _effect3 = sqlClient.Update("H_TEST", new List<object> { new { DID = 1, UNAME2 = "user123" }, new { DID = 2, UNAME2 = "user124" } }).Only("UNAME2").ExecCommand();

SQL-запросы:

update [dbo].[H_TEST] set [UNAME2]='user123' where [DID]=1
update [dbo].[H_TEST] set [UNAME2]='user124' where [DID]=2
  1. Удаление данных из таблицы:

Удаление всех данных из таблицы:

int _effect = sqlClient.Delete("H_Test").ExecCommand();

SQL-запрос:

delete [dbo].H_Test
``` **Удаление данных из таблицы в базе данных**

1. Удаление данных, соответствующих определённому условию:

    ```c#
    int _effect1 = sqlClient.Delete("H_Test").Where(new Filter { { "DID", OperType.GT, 200 } }).ExecCommand();
    ```

    SQL-запрос:

    ```sql
    delete [dbo].H_Test where [H_Test].[DID] > 200
    ```

2. Удаление без сущности данных по основному ключу:

    ```c#
    int _effect3 = sqlClient.Delete("H_Test", new List<object> { new { DID = 99, UNAME2 = "user123" }, new { DID = 100, UNAME2 = "user124" } }).ExecCommand();
    ```

    SQL-запросы:

    ```sql
    delete [dbo].H_Test where [DID]=99
    delete [dbo].H_Test where [DID]=100
    ```

3. Удаление с сущностью данных по основному ключу:

    ```c#
    class H_Test
    {
        public int DID
        {
            get; set;
        }
        public string UNAME
        {
            get; set;
        }
        public string UNAME2
        {
            get; set;
        }

    }
    ```

    ```c#
    int _effect4 = sqlClient.Delete("H_Test", new List<H_Test> { new H_Test { DID = 99, UNAME2 = "user123" }, new H_Test { DID = 100, UNAME2 = "user124" } }).ExecCommand();

    ```

    SQL-запросы:

    ```sql
    delete [dbo].H_Test where [DID]=99
    delete [dbo].H_Test where [DID]=100
    ```

4. Удаление данных без журнала базы данных:

    ```c#
    int _effect5 = sqlClient.TrunCate("H_Test").ExecCommand();
    ```

    SQL-запрос:

    ```sql
    TRUNCATE TABLE [dbo].H_Test
    ```

**Реализация case-оператора в HiSql**

HiSql предоставляет удобный способ работы с case-оператором в SQL, который автоматически адаптируется под различные базы данных. Разработчикам не нужно беспокоиться о конкретных синтаксических различиях между базами данных.

Пример кода на C#:

```c#
string _sql=sqlClient.Query("Hi_TabModel").Field("TabName as tabname").
    Case("TabStatus")
        .When("TabStatus>1").Then("'启用'")
        .When("0").Then("'未激活'")
        .Else("'未启用'")
    .EndAs("Tabs", typeof(string))
    .Field("IsSys")
    .ToSql()
    ;

В этом примере используется метод Case для определения условий и результатов на основе значения поля TabStatus. Затем результаты сохраняются в поле Tabs.

Синтаксис метода When:

  • When("TabStatus>1") — поддерживает операторы сравнения >, <, >=, <=, !=, <> (если оператор не входит в этот список, HiSql выдаст ошибку).
  • Если поле является строковым, то значение должно быть заключено в одинарные кавычки, например, When("TabName='TabName'").
  • Также можно использовать When("0"), что эквивалентно When("TabStatus=0").

Важно отметить, что при возникновении ошибки синтаксиса HiSql автоматически обнаружит её и выдаст соответствующее исключение. Кроме того, case-оператор не поддерживает вложенность, так как это может привести к снижению производительности.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
Apache-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/dotnetlowcode-hisql.git
git@api.gitlife.ru:oschina-mirror/dotnetlowcode-hisql.git
oschina-mirror
dotnetlowcode-hisql
dotnetlowcode-hisql
master