MYear.ODA
C# .Net Database ORM для Oracle DB2 MySql SqlServer SQLite MariaDB; чистая c# разработка, поддержка .NetCore 2.0, .Net standard
MYear.ODA — это компонент ORM для доступа к базе данных, который может работать с широко используемыми базами данных DB2, Oracle, SqlServer, MySql (MariaDB), SQLite; также можно легко использовать его для менее распространённых баз данных Informix, Sybase, Access; на данный момент MYear.ODA является наиболее полным компонентом C# ORM, поддерживающим синтаксис SQL; также он имеет хороший потенциал для расширения для работы с секционированными таблицами или распределёнными базами данных.
Разбиение на страницы, динамическое добавление условий, подзапросы, бесконечные соединения, объединение, группировка по, наличие, вложенные запросы, существование, вставка подзапросов, импорт и высокоскоростная загрузка — всё это характерные особенности ODA.
Он позволяет пользователям внедрять фрагменты кода SQL, а также писать собственный код SQL, и поддерживает процедуры (или пакеты Oracle); поскольку многие разработчики предпочитают простоту лямбда-выражений, ODA также расширил эту функцию.
ODA может повысить производительность разработчиков, стандартизировать способ написания кода и уменьшить проблемы с доступом к базе данных в больших командах разработчиков с разным уровнем навыков.
Производительность, функциональность, стабильность работы и параллельная производительность ODA являются очень сильными, не уступая Dapper, EF, SqlSugar.
Примечание: уже есть реальные проекты, которые свободно переключаются между тремя базами данных Oracle, Mysql и SqlServer.
Конечно, при создании таблиц следует избегать ключевых слов различных баз данных и обращать внимание на чувствительность к регистру записей данных в разных базах данных.
ODA использует синтаксис цепочечного программирования, напрямую сопоставляя SQL-запросы, поэтому синтаксис ODA похож на SQL, только Select, Insert, Update и Delete помещаются после. Поскольку ODA напрямую отображает SQL-запросы, он не выполняет никаких преобразований, как EF, что приводит к сложным и неэффективным SQL-запросам, которые трудно оптимизировать. При использовании ODA, если вы запутались, вы можете использовать SQL-запрос для вывода соответствующего синтаксиса ODA; обучение стоит очень дёшево, и его легко освоить, и вам не нужно тратить много времени на изучение, как с EF. Чтобы обеспечить совместимость с различными базами данных, SQL-запросы, генерируемые ODA, являются стандартными и универсальными; некоторые часто используемые, но несовместимые части реализованы внутри ODA (например, рекурсивные древовидные запросы и разбиение на страницы).
Методы MYear.ODA Select, Insert, Update, Delete и Procedure используются в качестве окончательных методов выполнения; когда эти методы вызываются, ODA отправляет сгенерированный SQL-запрос в базу данных для выполнения.
В информационных системах управления бизнес-функции не требуют максимальной производительности, достаточно удовлетворить общие требования взаимодействия человека с компьютером; но в базовых фреймворках или глобальных программах (таких как компоненты ORM и контейнеры AOP) мы стремимся к максимальной производительности при достижении определённого масштаба параллелизма. Производительность ORM влияет на общую производительность системы, и её использование, удобство обслуживания и влияние на разработчиков имеют всестороннее влияние на производительность всей системы. Из-за инвазивности ORM плохой ORM может привести разработчиков в заблуждение и привести их к бездонной яме; EF — хороший пример обратного обучения. Данные и производительность отображения EF не очень хороши, скорость генерации SQL-запросов низкая, но самая ненадёжная часть — это сгенерированные SQL-запросы. Сгенерированные EF SQL-запросы содержат множество преобразований и очень сложны, часто не могут использовать индексы и не поддаются оптимизации, что делает выполнение этих запросов в базе данных чрезвычайно медленным. Кроме того, синтаксис EF и Linq требует больших усилий для изучения, а эффективность разработки низкая, код трудно поддерживать, и в целом это кошмар. Хотя производительность ORM сама по себе не так важна (хотя производительность ODA очень сильна), ключевым моментом является то, что ORM не должен вводить разработчиков в заблуждение, а затем обеспечивать стандартизированный доступ к коду программы базы данных, повышать удобство сопровождения программы и одновременно повышать эффективность разработки, поддерживать последующие расширения приложений (такие как секционирование, секционирование таблиц, совместное использование нескольких баз данных) и ORM должны быть универсальными для баз данных, одновременно ограничивая разработчиков от использования специфичных для базы данных функций. Это цель ORM. Чтение одной записи данных Dapper немного опережает ODA, но время прогрева (первая запись) довольно длительное. ODA явно превосходит EF и SqlSugar; особенно EF значительно уступает остальным. SQL генерация производительности. Dapper не сравнивается, поскольку у него нет этой функции; скорость генерации операторов EF просто невыносима. ODA в несколько раз лучше, чем Sqlsugar. Запрос на постраничный поиск. Dapper, без учёта функций, не сравнивается; EF, ODA, Sqlsugar — разница в производительности незначительна. Использование ODA
Подключение к базе данных
// Глобальная настройка
ODAContext.SetODAConfig(DbAType.MsSQL, "server=localhost;database=master;uid=sa;pwd=sa;");
// Настройка для отдельного контекста
var ctx = new ODAContext(DbAType.MsSQL,"server=localhost;database=master;uid=sa;pwd=sa;");
Запрос
В ODA можно легко использовать ключевые слова SQL.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
object data = U.Where(U.USER_NAME == "Lambda")
.And(U.IS_LOCKED == "N")
.And(U.STATUS == "O")
.Select(U.USER_ACCOUNT, U.USER_PASSWORD.As("PWD"), U.USER_NAME, U.PHONE_NO, U.EMAIL_ADDR,U.ADDRESS,U.CREATED_DATE);
SELECT T0.USER_ACCOUNT, T0.USER_PASSWORD AS PWD, T0.USER_NAME, T0.PHONE_NO, T0.EMAIL_ADDR
, T0.ADDRESS, T0.CREATED_DATE
FROM SYS_USER T0
WHERE T0.USER_NAME = 'Lambda'
AND T0.IS_LOCKED = 'N'
AND T0.STATUS = 'O'
Для упрощения однотабличного запроса до сущности ODA предоставляет метод SelectM, который возвращает данные по умолчанию для сущности. Этот метод является повторной инкапсуляцией универсального метода Select<> и работает аналогично ему.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
List<SYS_USER> data = U.Where(U.CREATED_BY == "Insert", U.IS_LOCKED == "N", U.STATUS == "O")
.SelectM(U.USER_ACCOUNT, U.USER_NAME, U.PHONE_NO, U.EMAIL_ADDR, U.CREATED_DATE);
SELECT T0.USER_ACCOUNT, T0.USER_NAME, T0.PHONE_NO, T0.EMAIL_ADDR, T0.CREATED_DATE
FROM SYS_USER T0
WHERE T0.CREATED_BY = 'Insert'
AND T0.IS_LOCKED = 'N'
AND T0.STATUS = 'O'
Возвращаемый тип сущности может быть любым пользовательским типом, не обязательно совпадающим с сущностью базы данных. Универсальный метод Select<> не предъявляет особых требований к типу передаваемой сущности, и его свойства будут присвоены соответствующим образом, если они совпадают с именами полей запроса. Количество свойств в сущности не обязательно должно совпадать с количеством полей в запросе.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
List<SYS_USER> data = U.Where(U.CREATED_BY.Like("Import%"))
.And(U.IS_LOCKED == "N")
.And(U.STATUS == "O")
.And(U.EMAIL_ADDR.IsNotNull)
.Select<SYS_USER>(U.USER_ACCOUNT, U.USER_NAME, U.PHONE_NO, U.EMAIL_ADDR);
SELECT T0.USER_ACCOUNT, T0.USER_NAME, T0.PHONE_NO, T0.EMAIL_ADDR
FROM SYS_USER T0
WHERE T0.CREATED_BY LIKE 'Import%'
AND T0.IS_LOCKED = 'N'
AND T0.STATUS = 'O'
AND T0.EMAIL_ADDR IS NOT NULL
ODAContext ctx = BizContext.GetContext();
int total = 0;
var U = ctx.SYS_USER();
var data = U.Where(U.CREATED_BY.ContainLeft("Import"), U.IS_LOCKED == "N")
.SelectM(0,20,out total, U.CREATED_BY,U.CREATED_DATE, U.USER_ACCOUNT, U.USER_NAME, U.PHONE_NO, U.EMAIL_ADDR);
SELECT T0.CREATED_BY, T0.CREATED_DATE, T0.USER_ACCOUNT, T0.USER_NAME, T0.PHONE_NO
, T0.EMAIL_ADDR
FROM SYS_USER T0
WHERE T0.CREATED_BY LIKE 'Import%'
AND T0.IS_LOCKED = 'N';
SELECT COUNT(*) AS TOTAL_RECORD
FROM SYS_USER T0
WHERE T0.CREATED_BY LIKE 'Import%'
AND T0.IS_LOCKED = 'N'
Часто при запросе к базе данных требуется только первая строка данных. Для упрощения работы приложения ODA предлагает метод для запроса первой строки данных и возврата динамического типа данных. Результат будет динамическим типом, значения которого можно получить по именам полей запроса.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var data = U.Where(U.CREATED_BY == "InsertModel", U.IS_LOCKED == "N", U.USER_NAME.IsNotNull)
.SelectDynamicFirst(U.USER_ACCOUNT, U.USER_NAME, U.PHONE_NO, U.EMAIL_ADDR);
string UserName = data.USER_NAME; ///属性 USER_NAME 与 USER_NAME 的ColumnName一致,如果没有数据则返回null
SELECT T0.USER_ACCOUNT, T0.USER_NAME, T0.PHONE_NO, T0.EMAIL_ADDR
FROM SYS_USER T0
WHERE T0.CREATED_BY = 'InsertModel'
AND T0.IS_LOCKED = 'N'
AND T0.USER_NAME IS NOT NULL;
SELECT COUNT(*) AS TOTAL_RECORD
FROM SYS_USER T0
WHERE T0.CREATED_BY = 'InsertModel'
AND T0.IS_LOCKED = 'N'
AND T0.USER_NAME IS NOT NULL
Иногда создание отдельного класса сущности для небольшого запроса может быть слишком трудоёмким. ODA сама предоставляет динамический тип возвращаемого значения, что очень удобно для программ, обрабатывающих небольшое количество данных.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var data = U.Where(U.CREATED_BY == "Lambda", U.IS_LOCKED == "N", U.EMAIL_ADDR.IsNotNull)
.SelectDynamic(U.USER_ACCOUNT, U.USER_NAME, U.PHONE_NO, U.EMAIL_ADDR);
string UserName = "";
if (data.Count > 0)
UserName = data[0].USER_NAME; ///与 USER_NAME 的 ColumnName一致.
SELECT T0.USER_ACCOUNT, T0.USER_NAME, T0.PHONE_NO, T0.EMAIL_ADDR
FROM SYS_USER T0
WHERE T0.CREATED_BY = 'Lambda'
AND T0.IS_LOCKED = 'N'
AND T0.EMAIL_ADDR IS NOT NULL **Отбор неповторяющихся значений (Distinct)**
```C#
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var data = U.Where(U.IS_LOCKED == "N", U.EMAIL_ADDR.IsNotNull)
.Distinct.Select(U.USER_ACCOUNT, U.USER_NAME, U.PHONE_NO, U.EMAIL_ADDR);
SELECT DISTINCT T0.USER_ACCOUNT, T0.USER_NAME, T0.PHONE_NO, T0.EMAIL_ADDR
FROM SYS_USER T0
WHERE T0.IS_LOCKED = 'N'
AND T0.EMAIL_ADDR IS NOT NULL
Соединение запросов
ODA поддерживает InnerJoin, LeftJoin, RightJoin, и можно бесконечно Join. Условия On также очень гибкие, ODA в основном поддерживает все условия, которые поддерживаются SQL-операторами.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var R = ctx.SYS_ROLE();
var UR = ctx.SYS_USER_ROLE();
///LeftJoin\InnerJoin\RightJoin 可以无限连接,但实际上每种数据库都有对SQL语句长度作限制。
var data = U.InnerJoin(UR, U.USER_ACCOUNT == UR.USER_ACCUNT, UR.STATUS == "O")
.LeftJoin(R, UR.ROLE_CODE == R.ROLE_CODE, R.STATUS == "O")
.Where(U.STATUS == "O", R.ROLE_CODE == "Administrator")
.Select<UserDefineModel>(U.USER_ACCOUNT.As("UserAccount"), U.USER_NAME.As("UserName"), R.ROLE_CODE.As("Role"), R.ROLE_NAME.As("RoleName"));
SELECT T0.USER_ACCOUNT AS UserAccount, T0.USER_NAME AS UserName, T1.ROLE_CODE AS Role, T1.ROLE_NAME AS RoleName
FROM SYS_USER T0
INNER JOIN SYS_USER_ROLE T2
ON T0.USER_ACCOUNT = T2.USER_ACCOUNT
AND T2.STATUS = 'O'
LEFT JOIN SYS_ROLE T1
ON T2.ROLE_CODE = T1.ROLE_CODE
AND T1.STATUS = 'O'
WHERE T0.STATUS = 'O'
AND T1.ROLE_CODE = 'Administrator'
Простое внутреннее соединение
Внутреннее соединение имеет множество людей, которые используют только join, но для формы SELECT t1.* FROM TABLE1 T1, TABLE2 T2, TABLE3 T3, TABLE4 этот способ написания может быть незнакомым. Однако я считаю, что этот способ соединения проще и легче для чтения.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var R = ctx.SYS_ROLE();
var UR = ctx.SYS_USER_ROLE();
var data = U.ListCmd(UR,R)
.Where(U.USER_ACCOUNT == UR.USER_ACCOUNT,
UR.STATUS == "O",
UR.ROLE_CODE == R.ROLE_CODE,
R.STATUS == "O",
U.STATUS == "O",
R.ROLE_CODE == "Administrator")
.Select< UserDefineModel>(U.USER_ACCOUNT.As("UserAccount"), U.USER_NAME.As("UserName"),U.EMAIL_ADDR.As("Email"), R.ROLE_CODE.As("Role"), R.ROLE_NAME.As("RoleName"));
-------------
int total = 0;
var data = new ODAContext().From<SysUser, SysUserRole, SysRole, SysRoleAuthorization>()
.Where((u, ur, r, ra) => u.USER_ACCOUNT == ur.USER_ACCOUNT & ur.STATUS == "O"
& ur.ROLE_CODE == r.ROLE_CODE & r.STATUS == "O"
& r.ROLE_CODE == ra.ROLE_CODE & ra.IS_FORBIDDEN == "O" & ra.STATUS == "O"
& u.STATUS == "O" & (r.ROLE_CODE == "Administrator" | r.ROLE_CODE == "Admin") & u.IS_LOCKED == "N")
.Groupby((u, ur, r, ra) => new[] { r.ROLE_CODE, u.USER_ACCOUNT })
.Having((u, ur, r, ra) => ra.RESOURCE_ID.Count > 10)
.OrderbyAsc((u, ur, r, ra) => new[] { ra.RESOURCE_ID.Count })
.Select(0, 20, out total, (u, ur, r, ra) => new[] { r.ROLE_CODE, u.USER_ACCOUNT, ra.RESOURCE_ID.Count.As("ResourceCount") });
return data;
SELECT T0.USER_ACCOUNT AS UserAccount, T0.USER_NAME AS UserName, T0.EMAIL_ADDR AS Email, T1.ROLE_CODE AS Role, T1.ROLE_NAME AS RoleName
FROM SYS_USER T0, SYS_USER_ROLE T2, SYS_ROLE T1
WHERE T0.USER_ACCOUNT = T2.USER_ACCOUNT
AND T2.STATUS = 'O'
AND T2.ROLE_CODE = T1.ROLE_CODE
AND T1.STATUS = 'O'
AND T0.STATUS = 'O'
AND T1.ROLE_CODE = 'Administrator'
---------------
SELECT T2.ROLE_CODE,T0.USER_ACCOUNT,COUNT(T3.RESOURCE_ID) AS ResourceCount
FROM SYS_USER T0,SYS_USER_ROLE T1,SYS_ROLE T2,SYS_ROLE_AUTHORIZATION T3
WHERE (T0.USER_ACCOUNT = T1.USER_ACCOUNT
AND T1.STATUS = 'O'
AND T1.ROLE_CODE = T2.ROLE_CODE
AND T2.STATUS = 'O'
AND T2.ROLE_KEY = T3.ROLE_CODE
AND T3.IS_FORBIDDEN = 'O'
AND T3.STATUS = 'O'
AND T0.STATUS = 'O'
AND (T2.ROLE_CODE = 'Administrator' OR T2.ROLE_CODE = 'Admin')
AND T0.IS_LOCKED = 'N')
GROUP BY T2.ROLE_CODE,T0.USER_ACCOUNT
HAVING COUNT(T3.RESOURCE_ID) > 10
ORDER BY COUNT(T3.RESOURCE_ID) ASC
Вложенные подзапросы
Для вложенных подзапросов необходимо преобразовать один запрос в представление (ToView метод), после преобразования его можно использовать как обычный Cmd. В представлении ViewColumns — это набор полей представления. Текст запроса:
BizContext.GetContext(); var U = ctx.SYS_USER(); var R = ctx.SYS_ROLE(); var UR = ctx.SYS_USER_ROLE();
var UA = ctx.GetCmd(); var RA = ctx.SYS_ROLE_AUTHORIZATION();
var Admin = U.InnerJoin(UR, U.USER_ACCOUNT == UR.USER_ACCOUNT, UR.STATUS == "O") .InnerJoin(R, UR.ROLE_CODE == R.ROLE_CODE, R.STATUS == "O") .Where(U.STATUS == "O") .ToView(U.USER_ACCOUNT.As("SYS_USER"), U.USER_NAME, R.ROLE_CODE.As("SYS_ROLE"), R.ROLE_NAME); ////子查询
var data = Admin.InnerJoin(UA, UA.USER_ACCOUNT == Admin.ViewColumns[1],UA.IS_FORBIDDEN == "N")
.InnerJoin(RA,RA.ROLE_CODE == Admin.ViewColumns[2],RA.IS_FORBIDDEN =="N")
.Where(Admin.ViewColumns[0] == "MYEAR_Insert",
Admin.ViewColumns[2] == "Administrator")
.Select();
**Перевод текста на русский язык:**
BizContext.GetContext();
var У = ctx.SYS_USER();
var Р = ctx.SYS_ROLE();
var УР = ctx.SYS_USER_ROLE();
var ЮА = ctx.GetCmd<SysUserAuthorization>();
var РА = ctx.SYS_ROLE_AUTHORIZATION();
var Админ = У.InnerJoin(УР, У.USER_ACCOUNT == УР.USER_ACCOUNT, УР.STATUS == «О»)
.InnerJoin(Р, УР.ROLE_CODE == Р.ROLE_CODE, Р.STATUS == «О»)
.Где(У.STATUS == «О»)
.ТоВиев(У.USER_ACCOUNT.Ас("SYS_USER"), У.USER_NAME, Р.ROLE_CODE.Ас("SYS_ROLE"), Р.ROLE_NAME); ////подзапрос
var данные = Админ.InnerJoin(ЮА, ЮА.USER_ACCOUNT == Админ.ВиевКолоунс[1], ЮА.IS_FORBIDDEN == «Н»)
.InnerJoin(РА, РА.ROLE_CODE == Админ.ВиевКолоунс[2], РА.IS_FORBIDDEN == «Н»)
.Где(Админ.ВиевКолоунс[0] == «MYEAR_Insert»,
Админ.ВиевКолоунс[2] == «Администратор»)
.Выбрать();
В запросе используется язык программирования C#, а также язык запросов SQL. **Метод эквивалентен.**
Условия для фильтрации данных можно динамически добавлять в зависимости от бизнес-ситуации.
IS NULL/ IS NOT NULL условия можно напрямую вывести из полей, например: EMAIL_ADDR.IsNotNull.
```C#
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var UR = ctx.SYS_USER_ROLE();
var data = U.InnerJoin(UR, U.USER_ACCOUNT == UR.USER_ACCOUNT, UR.STATUS == "O")
.Where(U.STATUS == "O", U.EMAIL_ADDR.IsNotNull.Or(U.EMAIL_ADDR == "riwfnsse@163.com"), U.IS_LOCKED == "N")
.Where(UR.ROLE_CODE.In("Administrator", "Admin", "PowerUser", "User", "Guest"))
.Groupby(UR.ROLE_CODE)
.Having(U.USER_ACCOUNT.Count > 2)
.OrderbyAsc(U.USER_ACCOUNT.Count)
.Select(U.USER_ACCOUNT.Count.As("USER_COUNT"), UR.ROLE_CODE);
// Ниже приведён эквивалентный способ написания кода.
U.InnerJoin(UR, U.USER_ACCOUNT == UR.USER_ACCOUNT, UR.STATUS == "O");
U.Where(U.STATUS == "O");
U.Where(U.EMAIL_ADDR.IsNotNull.Or(U.EMAIL_ADDR == "riwfnsse@163.com"));
U.And(U.IS_LOCKED == "N");
U.Where(UR.ROLE_CODE.In("Administrator", "Admin", "PowerUser", "User", "Guest"));
U.Groupby(UR.ROLE_CODE);
U.Having(U.USER_ACCOUNT.Count > 2);
U.OrderbyAsc(U.USER_ACCOUNT.Count);
data = U.Select(U.USER_ACCOUNT.Count.As("USER_COUNT"), UR.ROLE_CODE);
SELECT COUNT(T0.USER_ACCOUNT) AS USER_COUNT, T1.ROLE_CODE
FROM SYS_USER T0
INNER JOIN SYS_USER_ROLE T1
ON T0.USER_ACCOUNT = T1.USER_ACCOUNT
AND T1.STATUS = 'O'
WHERE T0.STATUS = 'O'
AND (T0.EMAIL_ADDR IS NOT NULL
OR T0.EMAIL_ADDR = 'riwfnsse@163.com')
AND T0.IS_LOCKED = 'N'
AND T1.ROLE_CODE IN ('Administrator', 'Admin', 'PowerUser', 'User', 'Guest')
GROUP BY T1.ROLE_CODE
HAVING COUNT(T0.USER_ACCOUNT) > 2
ORDER BY COUNT(T0.USER_ACCOUNT) ASC;
Методы Groupby, Having и OrderbyAsc поддерживают функции;
Count, Max, Min, Sum, Upper, Lower и другие общие встроенные функции базы данных уже включены в поля ODA. Другие функции можно использовать с помощью ODA Function.
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var UR = ctx.SYS_USER_ROLE();
var data = U.InnerJoin(UR, U.USER_ACCOUNT == UR.USER_ACCOUNT, UR.STATUS == "O")
.Where(U.STATUS == "O", UR.ROLE_CODE.In("Administrator", "Admin", "PowerUser", "User", "Guest"))
.Groupby(UR.ROLE_CODE)
.Having(U.USER_ACCOUNT.Count > 2)
.OrderbyAsc(UR.ROLE_CODE,U.USER_ACCOUNT.Count)
.Select(U.USER_ACCOUNT.Count.As("USER_COUNT"), UR.ROLE_CODE);
SELECT COUNT(T0.USER_ACCOUNT) AS USER_COUNT, T1.ROLE_CODE
FROM SYS_USER T0
INNER JOIN SYS_USER_ROLE T1
ON T0.USER_ACCOUNT = T1.USER_ACCOUNT
AND T1.STATUS = 'O'
WHERE T0.STATUS = 'O'
AND T1.ROLE_CODE IN ('Administrator', 'Admin', 'PowerUser', 'User', 'Guest')
GROUP BY T1.ROLE_CODE
HAVING COUNT(T0.USER_ACCOUNT) > 2
ORDER BY T1.ROLE_CODE ASC, COUNT(T0.USER_ACCOUNT) ASC
IN/NOT IN имеет две перегрузки: одна — массив, другая — подзапрос.
ODAContext ctx = BizContext.GetContext();
var RA = ctx.SYS_ROLE_AUTHORIZATION();
var RS = ctx.SYS_RESOURCE();
///IN массив
RA.Where(RA.IS_FORBIDDEN == "N", RA.STATUS == "O", RA.ROLE_CODE.In("Administrator", "Admin", "PowerUser"));
///IN подзапрос
var data = RS.Where(RS.STATUS == "O", RS.ID.In(RA, RA.RESOURCE_ID))
.SelectM();
SELECT *
FROM SYS_RESOURCE T1
WHERE T1.STATUS = 'O'
AND T1.ID IN (
SELECT T0.RESOURCE_ID
FROM SYS_ROLE_AUTHORIZATION T0
WHERE T0.IS_FORBIDDEN = 'N'
AND T0.STATUS = 'O'
AND T0.ROLE_CODE IN ('Administrator', 'Admin', 'PowerUser')
)
ODAContext ctx = BizContext.GetContext();
var RA = ctx.SYS_ROLE_AUTHORIZATION();
//Exists условие подзапроса
var RS = ctx.SYS_RESOURCE();
RA.Where(RA.IS_FORBIDDEN == "N", RA.STATUS == "C", RA.RESOURCE_ID == RS.ID);
var data = RS.Where(RS.STATUS == "O", RS.Function.Exists(RA, RA.AllColumn))
.SelectM();
SELECT *
FROM SYS_RESOURCE T1
WHERE T1.STATUS = 'O'
AND EXISTS (
SELECT T0.*
FROM SYS_ROLE_AUTHORIZATION T0
WHERE T0.IS_FORBIDDEN = 'N'
AND T0.STATUS = 'C'
AND T0.RESOURCE_ID = T1.ID
)
Рекурсивные запросы ODA работают аналогично Oracle StartWith ConnectBy.
Принцип работы ODA: сначала с помощью where выбираются данные, необходимые для рекурсии, а затем выполняется рекурсия в памяти.
Поскольку рекурсия выполняется в памяти, все поля, используемые в рекурсии, должны быть включены в Select. Текст запроса:
的 с как 好一个级等。
递归有深度限制,ODA 限制最大深度是31层。
被递尺的原始数据越多性能下降很快,最好保被递彺筛选的数在10W条以内.
Перевод текста запроса на русский язык:
«...с как хорошо один уровень и т. д.».
Рекурсия имеет ограничение по глубине, максимальная глубина ODA ограничена 31 уровнем.
Чем больше исходных данных подвергается рекурсии, тем быстрее снижается производительность, поэтому лучше ограничить количество данных, подвергаемых рекурсии, до 10 Вт строк. Перевод текста на русский язык:
SELECT T2.ROLE_CODE,T0.USER_ACCOUNT,COUNT(T3.RESOURCE_ID) AS ResourceCount
FROM SYS_USER T0,SYS_USER_ROLE T1,SYS_ROLE T2,SYS_ROLE_AUTHORIZATION T3
WHERE (T0.USER_ACCOUNT = T1.USER_ACCOUNT
AND T1.STATUS = 'O'
AND T1.ROLE_CODE = T2.ROLE_CODE
AND T2.STATUS = 'O'
AND T2.ROLE_CODE = T3.ROLE_CODE
AND T3.IS_FORBIDDEN = 'O'
AND T3.STATUS = 'O'
AND T0.STATUS = 'O'
AND (T2.ROLE_CODE = 'Administrator' OR T2.ROLE_CODE = 'Admin')
AND T0.IS_LOCKED = 'N')
GROUP BY T2.ROLE_CODE,T0.USER_ACCOUNT
HAVING COUNT(T3.RESOURCE_ID) > 10
ORDER BY COUNT(T3.RESOURCE_ID) ASC
Обновление данных
Обычно оператор Update не обновляет все поля, а только указанные. Условия в операторе Update совпадают с условиями в запросе SELECT.
Пример на C#:
///Update 的 where 条件可参考 SELECT 语句
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
U.Where(U.LAST_UPDATED_BY == "InsertModel", U.IS_LOCKED == "N", U.STATUS == "O", U.EMAIL_ADDR.IsNotNull)
.Update(
U.USER_NAME == "новое имя", U.IS_LOCKED == "Y"
);
Пример SQL:
UPDATE SYS_USER
SET USER_NAME = 'новое имя', IS_LOCKED = 'Y'
WHERE LAST_UPDATED_BY = 'InsertModel'
AND IS_LOCKED = 'N'
AND STATUS = 'O'
AND EMAIL_ADDR IS NOT NULL
При использовании сущностей для обновления данных, значения свойств, равные null, не обновляются. Это связано с тем, что в большинстве случаев при использовании ORM-компонентов, интерфейс возвращает полный объект сущности или используется как контейнер для десериализации, включая те поля, которые не требуют обновления и равны null.
Пример на C#:
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
U.Where(U.CREATED_BY == "InsertModel", U.IS_LOCKED == "N", U.STATUS == "O", U.EMAIL_ADDR.IsNotNull)
.Update(new SYS_USER()
{
ADDRESS = "Свободное государство",
CREATED_DATE = DateTime.Now,
STATUS = "O",
USER_ACCOUNT = "NYear1",
USER_NAME = "Много лет 1",
USER_PASSWORD = "123",
IS_LOCKED = "N",
});
Пример SQL:
UPDATE SYS_USER
SET STATUS = 'O', CREATED_DATE = '2021/10/25 14:24:34', USER_ACCOUNT = 'NYear1', USER_NAME = 'Много лет 1', USER_PASSWORD = '123', ADDRESS = 'Свободное государство', IS_LOCKED = 'N'
WHERE CREATED_BY = 'InsertModel'
AND IS_LOCKED = 'N'
AND STATUS = 'O'
AND EMAIL_ADDR IS NOT NULL
Поддерживаются следующие операторы: +, -, *, /, %. В настоящее время при обновлении одного поля допускается использование только одного оператора.
Пример на C#:
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
var data = U.Where(U.CREATED_BY == "Lambda", U.IS_LOCKED == "N", U.EMAIL_ADDR.IsNotNull)
.Update(U.FAIL_TIMES == U.FAIL_TIMES + 1, U.USER_NAME == U.USER_ACCOUNT + U.EMAIL_ADDR );
Пример SQL:
UPDATE SYS_USER
SET FAIL_TIMES = FAIL_TIMES + 1, USER_NAME = USER_ACCOUNT + EMAIL_ADDR
WHERE CREATED_BY = 'Lambda'
AND IS_LOCKED = 'N'
AND EMAIL_ADDR IS NOT NULL
Условия в операторе Delete совпадают с условиями в SELECT.
Пример на C#:
ODAContext ctx = new ODAContext();
var U = ctx.GetCmd<SysUser>();
var data = U.Where(U.USER_ACCOUNT.ContainLeft ( "User1"), U.IS_LOCKED == "N", U.EMAIL_ADDR.IsNotNull)
.Delete();
Пример SQL:
DELETE FROM SYS_USER
WHERE USER_ACCOUNT LIKE 'User1%'
AND IS_LOCKED = 'N'
AND EMAIL_ADDR IS NOT NULL
Расширенные функции после версии 1.9.0
Пример на C#:
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER_();
var data = U.Where(w=>w.CREATED_BY.ContainLeft("User2") & w.IS_LOCKED == "N" & w.EMAIL_ADDR.IsNotNull)
.Delete();
Пример SQL:
DELETE FROM SYS_USER
WHERE (CREATED_BY LIKE 'User2%'
AND IS_LOCKED = 'N'
AND EMAIL_ADDR IS NOT NULL)
Расширенные функции после версии 1.9.0
Пример на C#:
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER_();
var data = U.Where(w => w.CREATED_BY == "Lambda" & w.IS_LOCKED == "N" & w.EMAIL_ADDR.IsNotNull)
.Update(v => new[] {
``` **v.FAIL_TIMES == v.FAIL_TIMES + 1, v.ADDRESS == v.USER_ACCOUNT + v.EMAIL_ADDR,v.USER_NAME == "Lambda更新" }**
— Данный фрагмент представляет собой набор выражений на языке программирования, который не удалось определить.
```SQL
UPDATE SYS_USER
SET FAIL_TIMES = FAIL_TIMES + 1, ADDRESS = USER_ACCOUNT + EMAIL_ADDR, USER_NAME = 'Lambda更新'
WHERE CREATED_BY = 'Lambda'
AND IS_LOCKED = 'N'
AND EMAIL_ADDR IS NOT NULL
— Это запрос на обновление данных в таблице SYS_USER в базе данных. Он устанавливает значения полей FAIL_TIMES, ADDRESS и USER_NAME для записей, где значение поля CREATED_BY равно 'Lambda', поле IS_LOCKED равно 'N', а поле EMAIL_ADDR не равно NULL.
ODAContext ctx = BizContext.GetContext();
var U = ctx.GetCmd<SysUser>();
U.Insert(U.STATUS == "O", U.CREATED_BY == "Insert", U.LAST_UPDATED_BY == "User1", U.LAST_UP-DATED_DATE == DateTime.Now, U.CREATED_DATE == DateTime.Now, U.EMAIL_ADDR == "riwfnsse@163.com",
U.USER_ACCOUNT == "MYEAR_Insert", U.USER_NAME == "多年", U.USER_PASSWORD == "123", U.FE_MALE == "M", U.FAIL_TIMES == 0, U.IS_LOCKED == "N");
INSERT INTO SYS_USER (STATUS, CREATED_BY, LAST_UPDATED_BY, LAST_UPDATED_DATE, CREATED_DATE
, EMAIL_ADDR, USER_ACCOUNT, USER_NAME, USER_PASSWORD, FE_MALE
, FAIL_TIMES, IS_LOCKED)
VALUES ('O', 'Insert', 'User1', '2021/10/25 14:36:04', '2021/10/25 14:36:04'
, 'riwfnsse@163.com', 'MYEAR_Insert', '多年', '123', 'M'
, 0, 'N')
— В этом фрагменте кода на языке C# используется метод Insert для вставки новой записи в таблицу SYS_USER. Значения полей STATUS, CREATED_BY и других задаются с помощью логических выражений. В запросе SQL также выполняется вставка новой записи с указанными значениями полей.
ODAContext ctx = BizContext.GetContext();
var U = ctx.GetCmd<SysUser>();
U.Insert(new SYS_USER()
{
ADDRESS = "自由国度",
CREATED_BY = "InsertModel",
CREATED_DATE = DateTime.Now,
FAIL_TIMES = 0,
STATUS = "O",
USER_ACCOUNT = "MYEAR_Model1122",
USER_NAME = "多年1",
USER_PASSWORD = "123",
IS_LOCKED = "N",
EMAIL_ADDR = "riwfnsse@163.com"
});
INSERT INTO SYS_USER (STATUS, CREATED_BY, CREATED_DATE, USER_ACCOUNT, USER_NAME
, USER_PASSWORD, EMAIL_ADDR, ADDRESS, FAIL_TIMES, IS_LOCKED)
VALUES ('O', 'InsertModel', '2021/10/25 14:39:21', 'MYEAR_Model1122', '多年1'
, '123', 'riwfnsse@163.com', '自由国度', 0, 'N')
— Здесь также используется метод Insert, но на этот раз для вставки модели данных SYS_USER с заданными значениями полей. В запросе SQL выполняется аналогичная операция.
ODAContext ctx = BizContext.GetContext();
var U = ctx.From<SysUser>();
U.Insert(a => new[]{a.ADDRESS == "自由国度",a.CREATED_BY =="Lambda", a.USER_NAME=="Lambda",a.CREATED_DATE == DateTime.Now, a.EMAIL_ADDR=="riwfnsse@163.com",
a.FAIL_TIMES == 0,a.STATUS =="O",a.USER_ACCOUNT=="MYear1" + Guid.NewGuid().ToString("N"),a.USER_PASSWORD=="123",a.IS_LOCKED =="N"}
);
INSERT INTO SYS_USER (ADDRESS, CREATED_BY, USER_NAME, CREATED_DATE, EMAIL_ADDR
, FAIL_TIMES, STATUS, USER_ACCOUNT, USER_PASSWORD, IS_LOCKED)
VALUES ('自由国度', 'Lambda', 'Lambda', '2021/10/25 14:40:32', 'riwfnsse@163.com'
, 0, 'O', 'MYear1fbbf0613ba2f44199b520ea93d40a594', '123', 'N')
— Этот фрагмент кода также использует метод Insert, но здесь применяется цепная запись условий для вставки данных. В запросе SQL выполняются аналогичные операции.
В этом разделе описывается процесс массовой загрузки данных в базу данных с использованием DataTable. Однако текст не содержит подробностей о том, как именно это делается. Обычно, чем больше система, тем более ценными являются ресурсы базы данных, и тем осторожнее следует применять транзакции.
Не стоит использовать транзакции там, где можно без них обойтись. Если возможно, сократите количество DML-операций в транзакциях, а также время выполнения транзакций.
Поскольку объекты базы данных блокируются до завершения транзакции, и только один пользователь может заблокировать объект одновременно, транзакции могут снижать параллельную производительность системы. Длительная блокировка объектов базы данных или возникновение ситуаций ожидания блокировки или взаимоблокировки могут иметь фатальные последствия для системы.
ODAContext ctx = new ODAContext();
var U1 = ctx.GetCmd<SysUser>();
ctx.BeginTransaction();
try
{
var U = ctx.GetCmd<SysUser>();
U.Where(U.USER_ACCOUNT == "User1", U.IS_LOCKED == "N", U.STATUS == "O", U.EMAIL_ADDR.IsNotNull)
.Update(U.USER_NAME == "новое имя", U.IS_LOCKED == "Y");
U1.Insert(U.STATUS == "O", U.USER_NAME == "User1", U.LAST_UPDATED_BY == "User1", U.LAST_UPDATED_DATE == DateTime.Now, U.CREATED_DATE == DateTime.Now,U.USER_ACCOUNT == "Nyear", U.USER_NAME == "много лет", U.USER_PASSWORD == "123", U.FE_MALE == "M", U.FAIL_TIMES == 0, U.IS_LOCKED == "N");
ctx.Commit();
}
catch
{
ctx.RollBack();
}
ODA предоставляет набор общих системных функций, которые часто используются в базах данных: MAX, MIN, COUNT, SUM, AVG, LENGTH, LTRIM, RTRIM, TRIM, ASCII, UPPER, LOWER. Эти функции вызываются непосредственно из полей, например: USER_ACCOUNT.Count.
ODAContext ctx = new ODAContext();
var U = ctx.GetCmd<SysUser>();
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Groupby(U.USER_ACCCOUNT)
.Select(U.Function.Count.As("CountAll"), U.USER_ACCOUNT.Count.As("CountOne"), U.USER_ACCOUNT.Upper.As("UPPER_ACC"), U.USER_ACCOUNT.Trim.Ltrim.As("TRIM_ACC"));
SELECT COUNT(*) AS CountAll,
COUNT(T0.USER_ACCOUNT) AS CountOne,
UPPER(T0.USER_ACCOUNT) AS UPPER_ACC,
LTRIM(T0.USER_ACCOUNT) AS TRIM_ACC
FROM SYS_USER T0
WHERE T0.STATUS = 'O'
AND T0.IS_LOCKED = 'N'
GROUP BY T0.USER_ACCOUNT;
Express метод позволяет разработчикам внедрять свои собственные SQL-скрипты в SELECT-поля. Поскольку выражения ODA представляют собой внедренные SQL-запросы, разработчики должны быть осторожны с рисками SQL-инъекций и возможностью использования выражений в разных базах данных.
ODAParameter p1 = new ODAParameter() { ColumnName = "Params1", DBDataType = ODAdbType.OVarchar, Direction = System.Data.ParameterDirection.Input, ParamsName = ODAParameter.ODAParamsMark + "Params1", ParamsValue = "Я первый параметр", Size = 2000 };
ODAParameter p2 = new ODAParameter() { ColumnName = "Params2", DBDataType = ODAdbType.OVarchar, Direction = System.Data.ParameterDirection.Input, ParamsName = ODAParameter.ODAParamsMark + "Params2", ParamsValue = "Это SQL-инъекция", Size = 2000 };
ODAContext ctx = new ODAContext();
var U = ctx.GetCmd<SysUser>();
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Select(U.Function.Express("1+1").As("COMPUTED"),
U.Function.Express(" null ").As("NULL_COLUMN"),
U.Function.Express(" 'Function( + " + ODAParameter.ODAParamsMark + "Params1, " + ODAParameter.ODAParamsMark + "Params2)' ", p1, p2).As("SQL_Injection"));
SELECT 1 + 1 AS COMPUTED,
null AS NULL_COLUMN,
'Function( + @Params1, @Params2)' AS SQL_Injection
FROM SYS_USER T0
WHERE T0.STATUS = @T1
AND T0.IS_LOCKED = @T2;
VisualColumn метод представляет собой еще одну оболочку для Express метода, предоставляя разработчикам удобство и избегая необходимости преобразования данных и рисков SQL-инъекции.
ODAContext ctx = new ODAContext();
var U = ctx.GetCmd<SysUser>();
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Select(U.Function.VisualColumn("HELLO , I am MYear software").As("STRING_COLUMN"), U.Function.VisualColumn(DateTime.Now).As("APPLICATION_DATETIME"), U.Function.VisualColumn(0).As("DIGIT_COLUMN"));
SELECT 'HELLO , I am MYear software' AS STRING_COLUMN,
@T1 AS APPLICATION_DATETIME,
0 AS DIGIT_COLUMN
FROM SYS_USER T0
WHERE T0.STATUS = 'O'
AND T0.IS_LOCKED = 'N';
CreateFunc метод позволяет добавлять пользовательские функции в SELECT поля. Однако, поскольку разные базы данных имеют значительные различия в вызове пользовательских функций, ODA не может обеспечить их универсальность. Поэтому, если требуется использование CreateFunc метода в разных базах данных, необходимо учитывать особенности схемы, пользователя, владельца базы данных и других объектов при создании базы данных.
ODAContext ctx = new ODAContext();
var RS = ctx.GetCmd<SysResource>();
object data = RS.Where(RS.STATUS == "O",RS.RESOURCE_TYPE =="MENU")
.Select(RS.AllColumn,RS.Function.CreateFunc("dbo.GET_RESOURCE_PATH", RS.ID).As("RESOURCE_PATH"));
SELECT T0.*,dbo.GET_RESOURCE_PATH(T0.ID) AS RESOURCE_PATH
FROM SYS_RESOURCE T0
WHERE T0.STATUS = 'O' AND T0.RESOURCE_TYPE = 'MENU';
SQL-оператор: case when условие. Тогда значение, когда условие, иначе значение по умолчанию
ODAContext ctx = new ODAContext();
var U = ctx.GetCmd<SysUser>();
Dictionary<ODAColumns, object> Addr = new Dictionary<ODAColumns, object>();
Addr.Add(U.ADDRESS.IsNull, "无用户地址数据...");
Addr.Add(U.ADDRESS.Like("%公安局%"), "被抓了?");
Dictionary<ODAColumns, object> phone = new Dictionary<ODAColumns, object>();
phone.Add(U.PHONE_NO.IsNull, "Этот человек очень ленив и ничего не оставил");
phone.Add(U.PHONE_NO == "110", "Маленький вор, беги!");
phone.Add(U.ADDRESS.NotLike("%公安局%"), "Был пойман?");
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Select(U.Function.CaseWhen(Addr, U.ADDRESS).As("ADDRESS"), U.Function.CaseWhen(phone, "110").As("PHONE_NO"));
--------------------------------
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Select(U.CaseWhen(U.ADDRESS.IsNull).Then("无用户地址数据..")
.When(U.ADDRESS.Like("%公安局%")).Then("Был пойман?")
.Else(U.ADDRESS).End().As("ADDRESS"),
U.CaseWhen(U.PHONE_NO.IsNull).Then("Этот человек очень ленив и ничего не оставил")
.When(U.PHONE_NO == "110").Then("Маленький вор, беги!")
.When(U.ADDRESS.NotLike("%公安局%")).Then("Был пойман?")
.Else(U.ADDRESS).End().As("PHONE_NO"));
return data;
Выбор значений на основе условий
SELECT CASE
WHEN T0.ADDRESS IS NULL THEN '无用户地址数据...'
WHEN T0.ADDRESS LIKE '%公安局%' THEN 'Был пойман?'
ELSE T0.ADDRESS
END AS ADDRESS
, CASE
WHEN T0.PHONE_NO IS NULL THEN 'Этот человек очень ленив и ничего не оставил'
WHEN T0.PHONE_NO = '110' THEN 'Маленький вор, беги!'
WHEN T0.ADDRESS NOT LIKE '%公安局%' THEN 'Был пойман'
ELSE '110'
END AS PHONE_NO
FROM SYS_USER T0
WHERE T0.STATUS = 'O'
AND T0.IS_LOCKED = 'N';
--------------------
SELECT ( CASE WHEN T0.ADDRESS IS NULL THEN '无用户地址数据..' WHEN T0.ADDRESS LIKE '%公安局%' THEN 'Был пойман?' ELSE T0.ADDRESS END ) AS ADDRESS,
( CASE WHEN T0.PHONE_NO IS NULL THEN 'Этот человек очень ленив и ничего не оставил' WHEN T0.PHONE_NO = '110' THEN 'Маленький вор, беги!' WHEN T0.ADDRESS NOT LIKE '%公安局%' THEN 'Был пойман?' ELSE '110' END ) AS PHONE_NO
FROM SYS_USER T0
WHERE T0.STATUS = 'O'
AND T0.IS_LOCKED = 'N'
Обработка пустых значений
NullDefault — это повторная упаковка метода CaseWhen для удобства использования.
ODAContext ctx = new ODAContext();
var U = ctx.GetCmd<SysUser>();
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Select(U.Function.NullDefault(U.ADDRESS, "无用户地址数据...").As("ADDRESS"), U.Function.NullDefault(U.PHONE_NO,110).As("PHONE_NO"));
------
ODAContext ctx = BizContext.GetContext();
var U = ctx.SYS_USER();
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Select(U.Address.NullDefault("无用户地址数据...").As("ADDRESS"), U.PhoneNo.NullDefault(110).As("PHONE_NO"));
return data;
SELECT (CASE
WHEN T0.ADDRESS IS NULL THEN
'无用户地址数据...'
ELSE
T0.ADDRESS
END) AS ADDRESS,
(CASE
WHEN T0.PHONE_NO IS NULL THEN
110
ELSE
T0.PHONE_NO
END) AS PHONE_NO
FROM SYS_USER T0
WHERE T0.STATUS = 'O'
AND T0.IS_LOCKED = 'N';
------
SELECT ( CASE WHEN T0.ADDRESS IS NULL THEN '无用户地址数据...' ELSE T0.ADDRESS END ) AS ADDRESS,
( CASE WHEN T0.PHONE_NO IS NULL THEN 110 ELSE T0.PHONE_NO END ) AS PHONE_NO
FROM SYS_USER T0
WHERE T0.STATUS = 'O'
AND T0.IS_LOCKED = 'N'
Преобразование данных с использованием Case
В SQL оператор case используется для сравнения значения поля с заданным значением и возврата другого значения в случае совпадения.
ODAContext ctx = new ODAContext();
var U = ctx.GetCmd<SysUser>();
Dictionary<object, object> Addr = new Dictionary<object, object>();
Addr.Add(U.Function.Express(" NULL "), "无用户地址数据...");
Addr.Add("天堂", "人生最终的去处");
Dictionary<object, object> phone = new Dictionary<object, object>();
phone.Add(U.Function.Express(" NULL "), "Этот человек очень ленив и ничего не оставил");
phone.Add( "110", "Маленький вор, беги!");
phone.Add(U.ADDRESS, "Данные ошибочны, телефон и адрес совпадают");
object data = U.Where(U.STATUS == "O", U.IS_LOCKED == "N")
.Select(U.Function.Case(U.ADDRESS,Addr, U.ADDRESS).As("ADDRESS"), U.Function.Case(U.PHONE_NO,phone, U.PHONE_NO).As("PHONE_NO");
``` **Данные содержания преобразования Case**
SQL-оператор CASE позволяет выбрать одно из нескольких значений в зависимости от условия. В данном случае оператор используется для обработки полей T0.ADDRESS и T0.PHONE_NO. Если значение поля равно NULL, то возвращается строка «无用户地址数据...». Если значение поля T0.ADDRESS равно «天堂», то возвращается «人生最终的去处». В противном случае возвращается значение самого поля.
Для поля T0.PHONE_NO при значении «110» возвращается значение поля T0.ADDRESS, при значении «119» — «拿水来», в остальных случаях возвращается значение самого поля T0.PHONE_NO.
Запрос выбирает данные из таблицы SYS_USER, где статус равен «O», а IS_LOCKED равен «N». Для выбранных данных выполняется преобразование полей ADDRESS и PHONE_NO с использованием оператора CASE.
**Данные содержания преобразования Decode**
Метод ODAContext.Decode используется для преобразования значений полей в соответствии с заданными условиями. Метод принимает три параметра: исходное значение, значение по умолчанию и список пар ключ-значение. Если исходное значение совпадает с одним из ключей, то в качестве результата возвращается соответствующее значение из пары. В противном случае в качестве результата возвращается значение по умолчанию.
В запросе метод используется для преобразования поля RESOURCE_TYPE в таблице SYS_RESOURCE. Если значение поля совпадает с одним из заданных ключей, то в результате возвращается соответствующее значение. В противном случае возвращается значение «未知类型».
Запрос выбирает данные из таблицы SYS_RESOURCE, где статус равен «О», а тип ресурса равен «MENU». Для выбранного значения поля RESOURCE_TYPE выполняется преобразование с использованием метода ODAContext.Decode. **Текст запроса:**
DataColumn("STATUS"));
data.Columns.Add(new DataColumn("DUMMY"));
data.Columns.Add(new DataColumn("USER_ACCOUNT"));
data.Columns.Add(new DataColumn("USER_NAME"));
data.Columns.Add(new DataColumn("USER_PASSWORD"));
data.Columns.Add(new DataColumn("IS_LOCKED"));
for (int i = 0; i < 10000; i++)
{
object[] dr = new object[]
{
"自由国度",
"User1" ,
DateTime.Now,
"riwfnsse@163.com",
"User1" ,
DateTime.Now,
0,
"O",
"Dummy",
"ImportUser" + i.ToString(),
"导入的用户" + i.ToString(),
"123",
"N"
};
data.Rows.Add(dr);
}
List<SYS_USER> DataList = ODA.DBAccess.ConvertToList<SYS_USER>(data);
**Перевод текста на русский язык:**
ДатаКолоун («СТАТУС»);
дата.Колумнс.Адд (новый ДатаКолоун («ДАММИ»));
дата.Колумнс.Адд (новый ДатаКолоун («УСЕР_АКАУНТ»));
дата.Колумнс.Адд (новый ДатаКолоун («УСЕР_НАМЕ»));
дата.Колумнс.Адд (новый ДатаКолоун («УСЕР_ПАССВОРД»));
дата.Колумнс.Адд (новый ДатаКолоун («ИС_ЛОКЭД»));
фор (инт я = 0; я < 10000; я++)
{
объект[] др = новый объект[]
{
«свободный государство»,
«Усер1»,
ДатаТим.Нау,
«риуфнсэ@163 точка ком»,
«Усер1»,
ДатаТим.Нау,
0,
«О»,
«Дамми»,
«ИмпортУсер» + я.ТоСтрока,
«импортный пользователь» + я.ТоСтрока,
«123»,
«Н»
};
дата.Роус.Адд (др);
}
Лист<СИС_УСЕР> ДатаЛист = ОДА.ДБАКцесс.КонвертТол<СИС_УСЕР>(дата); Третий — это инструмент для копирования данных из одной таблицы в другой базе данных.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )