Форум программистов, компьютерный форум, киберфорум
C#: ASP.NET Core
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.66/111: Рейтинг темы: голосов - 111, средняя оценка - 4.66
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330

Архитектура построения БД linq2db

06.01.2021, 08:43. Показов 25705. Ответов 111

Студворк — интернет-сервис помощи студентам
Добрый день!

У меня вот такая задача.
Нужно создать БД CodeFirst на linq2db. (99% что это linq2db).

Эту базу будет использовать более 10 мелких приложений.

Как сделать правильно, чтобы методы выборки, создания таблици и т.д. были не конкретно в каждом приложении, а вынесены в стороннюю библиотеку?
Чтобы при изменении таблицы или выборки, не приходилось менять это во всех 10 приложениях, а только в одном месте.

Очень бы хотелось увидеть реальный пример использования.

Где посмотреть уже готовые решения на основе linq2db?
Не пример использования запросов из справки linq2db, а именно реальную архитектуру построения модели и контроллера.

Буду очень благодарен за любую помощь!
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.01.2021, 08:43
Ответы с готовыми решениями:

В указанном dsn архитектура драйвера и архитектура приложения не соответствуют друг другу
Добрый день. При запуске программы выскакивает вот такая вот ошибка. В чем может быть проблема и как ее исправить?

архитектура процессоров и компьютерная архитектура,Intel32. для первокурсников
сабж. кто чем может помочь юному,непонемающему в этой области человеку.желательно книгами.спасибо.

Как ускорить запрос Linq2db?
Всем привет) Использую linq2db для запросов в базу данных. Данных не много. Но очень долго работает. Не подскажете как оптимизировать...

111
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
15.02.2021, 14:26  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Usaga Посмотреть сообщение
Это галимая денормализация
Начитался демонизирующих статей enum в mysql.
Перешёл на int в mysql + enum в C#.
Минусы есть, но плюсов больше конечно. И проще получается с созданием и изменением таблиц.
Спасибо.


А сейчас столкнулся с проблемой блокировки таблиц.
Если блокировать через sql запросы в программе, то всё ок.
SQL
1
2
3
4
LOCK TABLES `city` WRITE;
SELECT * FROM `city` LIMIT 1;
-- что-то ещё
UNLOCK TABLES;
а вот через linq2db после блокировки таблицы, при попытке сделать этой таблице select получаю ошибку ("Table 'x' was not locked with LOCK TABLES")

Встроенных локов в linq2db не нашёл, (только транзакции) делаю вот так:
C#
1
2
3
4
5
db.Execute($"LOCK TABLES city WRITE;");
 
db.City.FirstOrDefault(); 
 
db.Execute($"UNLOCK TABLES;");
Мне нужно, чтобы никакое другое приложение в этот момент не могло не то что изменить, а даже получить (select) из этой таблицы.
Транзакции как мне кажется здесь не подходят.
0
Эксперт .NET
 Аватар для Usaga
14731 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,857
15.02.2021, 15:36
BeginnerCoderCS, распишите подробнее идею с блокировками. С вероятностью в 90% вы свою хотелку неверно реализуете.
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
15.02.2021, 16:11  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
распишите подробнее идею с блокировками. С вероятностью в 90% вы свою хотелку неверно реализуете.
На удалённом сервере к которому я подключаюсь через api есть некие данные (допустим города и таблица City).
Они периодически меняются.
То есть допустим раз в 60 минут нужно проверять нет ли чего-то нового на сервере, и если есть, то сохранять изменения в БД.

Так как эти данные используются несколькими приложениями, то каждое из этих приложений должно иметь возможность запросить данные, и обновить их, если нужно.

Так вот.

Я создал отдельную таблицу, в которой будет храниться последнее изменение других таблиц.
SQL
1
2
3
4
5
6
CREATE TABLE `changes` (
    `TableName` VARCHAR(100),
    `Status` VARCHAR(15),
    `TimeStamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`TableName`) USING BTREE
)
Логика такая.
Я проверяю последнее изменение таблицы `City` в таблице `changes`.
Данные в таблице `changes` вида (TableName, Status, TimeStamp) ("City", "OK", "2021-02-15 15:50")

То есть я проверю когда последний раз получались данные с сервера, и если прошло больше чем 60 минут, то устанавливаю статус "BUSY" ("City", "BUSY", "2021-02-15 15:50") и запрашиваю новые данные.

Вот нужно чтобы в этот момент никакое другое приложение не получило эту строку, и не начало так же параллельно получать данные с сервера.

Если сделать транзакцию, то второе приложение сможет работать с этой таблицей `changes`, и успеет получить значение которое ещё было "OK".

Поэтому
SQL
1
2
3
4
LOCK TABLES `changes` WRITE;
SELECT * FROM `changes` WHERE `TableName` = 'City' AND `Status` = 'OK' AND `TimeStamp` < '2021-02-15 14:50';
UPDATE `changes` SET    `Status` = 'BUSY' WHERE `TableName` = 'City';
UNLOCK TABLES;
То есть чтобы в момент, когда принимается решение в одном приложении "Нужно ли обновлять данные в таблице `City`" никто другой не мог получить доступ к таблице `changes`.
0
800 / 583 / 207
Регистрация: 21.02.2019
Сообщений: 2,095
15.02.2021, 16:11
Usaga,
.. очень похоже на архитектуру "Пока Машенька из логистики списывает товар (и отлучилась попить кофе), Вася из маркетинга не сможет даже увидеть этот товар, не то что продать..." ...
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
15.02.2021, 16:17  [ТС]
Это всё работает на SQL.
А с через linq2db не хочет работать.

Добавлено через 4 минуты
Цитата Сообщение от carrotik Посмотреть сообщение
Usaga,
.. очень похоже на архитектуру "Пока Машенька из логистики списывает товар (и отлучилась попить кофе), Вася из маркетинга не сможет даже увидеть этот товар, не то что продать..." ...
Немного не так.
Это блокируется на время пока устанавливается статус "BUSY", чтобы все последующие не успели взять строку со статусом "ОК" и не ломонулись следом стучаться к удалённому апи за обновлениями, которые к этому времени уже будут получены другим приложением.

Есть другие идеи?
0
Эксперт .NET
 Аватар для Usaga
14731 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,857
15.02.2021, 17:03
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Есть другие идеи?
Я так и не понял конкретики задумки. Вообще, блокировкт должны производиться на уровне приложения, а не СУБД. Пример с городами какой-то странный. Если вам надо "залочить" запись, то для этого нужно в базе завести поле с флагои или отдельную таблицу и там сохранять информацию о блокировках. Или, если сервер приложения единый для всех клиентов, то в оперативной памяти сервера.

На уровне СУБД блокировки, тем более длительные, приведут к существенным проблемам производительности.

Блокировки уровня СУБД должны использоватья для решения конкурентного доступа разных транзакций, а не для того, что вы загадали. Так не делают.
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
15.02.2021, 17:29  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
На уровне СУБД блокировки, тем более длительные, приведут к существенным проблемам производительности.
Пусть это будут не города, а курс рубля к доллару, и ограничение запросов к апи курса $ раз в 60 минут.

То есть каждое приложение не может постоянно долбиться туда.
А приложение не одно, и нужно сделать, чтобы раз в 60 минут любое из запущенных приложений могло получить новый курс.

OK, можно конечно сделать блокировку на уровне приложения.
Но если приложения будут находиться на разных серверах/компьютерах? Это же mysql и она не локальная.

Вы вообще не используете блокировку таблиц на linq2db?
0
Эксперт .NET
 Аватар для Usaga
14731 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,857
15.02.2021, 17:32
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Пусть это будут не города, а курс рубля к доллару, и ограничение запросов к апи курса $ раз в 60 минут.
То есть каждое приложение не может постоянно долбиться туда.
А приложение не одно, и нужно сделать, чтобы раз в 60 минут любое из запущенных приложений могло получить новый курс.
OK, можно конечно сделать блокировку на уровне приложения.
Но если приложения будут находиться на разных серверах/компьютерах? Это же mysql и она не локальная.
Я вообще не понимаю зачему тут блокировки какие-то.

Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Вы вообще не используете блокировку таблиц на linq2db?
Нет. Вообще ни в каком виде. Любые ограничения доступа к данным мы формируем на уровне сервера приложения. СУБД тут тупо как хранилище данных умеющее в корректный конкурентный доступ к данным.
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
15.02.2021, 18:02  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Я вообще не понимаю зачему тут блокировки какие-то.
Ограничение на количество запросов к апи, но данные нужно постоянно обновлять.
Отдельное приложение под обновления это уж слишком как по мне.

Без блокировки.
Первое приложение запустилось и проверяет актуальность курса валют.
Последнее изменение 61 минута и статус "OK".
Чтобы все остальные приложения не пошли запрашивать данные с апи, в таблице указывается статус "BUSY".

НО.
Пока проверялась необходимость запроса новых курсов валют и устанавливался статус "BUSY" первым приложением, вполне вероятно, что второе приложение так же запросило актуальность данных, и уже получило себе статус "OK" и 61 минута. И так же отправляет статус "BUSY" и параллельно с первым идёт запрашивать данные с api.


После получения с апи и обновления данных в БД, устанавливаем статус "ОК" и новое время обновления.
Второе приложение получает ограничение апи запросов, ждёт снятия ограничения, и запрашивает ещё раз, или падает, выключается и т.д.


Ещё может быть такое: приложение упало, отключили электричество и т.д., и приложение не установило статус "OK" и там на всё время останется статус "BUSY" и данные никогда не будут обновляться.
Значит при запросе нужно получать данные, и проверять как давно установлен статус "BUSY".
То есть нужно проверить ещё одно условие.
Допустим на обновление данных нужно 5 минут, значит если статус "BUSY" и изменения больше чем 10 минут, то нужно обновить время, и получить новые данные.

И это всё с удалённой БД и приложениями на разных компьютерах.

Не используя блокировку таблицы не могу придумать как это можно реализовать.
0
Эксперт .NET
 Аватар для Usaga
14731 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,857
16.02.2021, 09:30
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Не используя блокировку таблицы не могу придумать как это можно реализовать.
Описанный выше сценарий реализуется силами сервера приложения. СУБД и её таблицы тут вообще ни причём. Ваш сервер приложения (консольное приложение, обсуживающее запросы клиентов) само должно кешировать нужные данные и решать когда их обновлять. Это крайне распространённый подход.

А у вас, я так понял, все клиенты напрямую к базе ломятся, да?)
2
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
16.02.2021, 10:01  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
А у вас, я так понял, все клиенты напрямую к базе ломятся, да?)
ага

p.s. О хоспаде, пошёл читать про кеш )
Правльно же я понял вас?
0
Эксперт .NET
 Аватар для Usaga
14731 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,857
16.02.2021, 10:04
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Правльно же я понял вас?
Да. Вы можете в своих клиентах кеш реализовать. Они всё равно будут давать нагрузку на СУБД, большую, чем если бы кеш был централизованным. Но всё равно сильно лучше, чем ничего.
1
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
18.03.2021, 18:25  [ТС]
Не создаю новую ветку, думаю этот вопрос будет актуален здесь.

Столкнулся с проблемой, когда из-за длительного ожидания MySQL разрывает соединение.

Допустим вот так создаётся коннекшн
C#
1
2
3
4
5
6
public class DB : LinqToDB.Data.DataConnection
{
    public DB(string connectionString)
        : base(LinqToDB.ProviderName.MySql, connectionString)
    { }
}
С using создаю подключение, и как я надеюсь всё удляется, освобождается (соединение, пул и что там ещё должно чиститься или освобождаться)
C#
1
2
3
4
using (var db = new DB(""))
{
 
}

Но выполнять код в using(var db..) не всегда есть возможность.

Конкретно с linq2db как гарантированно закрыть соединение, очистить ресурсы, освободить пул соединений?

Методы Close() и Dispose() достаточно?
C#
1
2
3
4
5
var db = new DB("");
////
///
db?.Close();
db?.Dispose();

Что если это всё реализовать в классе подключения?
И вызывать просто db.DisConnect();
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
public class DB : LinqToDB.Data.DataConnection
{
    public DB(string connectionString)
        : base(LinqToDB.ProviderName.MySql, connectionString)
    { }
 
    public void DisConnect()
    {
        base.Close();
        base.Dispose();
    }
 
}
Добавлено через 3 часа 16 минут
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Конкретно с linq2db как гарантированно закрыть соединение, очистить ресурсы, освободить пул соединений?
Методы Close() и Dispose() достаточно?
Usaga, Элд Хасп, и все желающие помогите )))
0
282 / 485 / 12
Регистрация: 21.06.2019
Сообщений: 3,020
18.03.2021, 18:38
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Конкретно с linq2db как гарантированно закрыть соединение, очистить ресурсы, освободить пул соединений?
Выкинуть нафиг linq2db (как и любую другую ОРМ) и делать все ручками конечно же. Как все нормальные люди.
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
18.03.2021, 18:43  [ТС]
Цитата Сообщение от Катафалк Посмотреть сообщение
Выкинуть нафиг linq2db (как и любую другую ОРМ) и делать все ручками конечно же. Как все нормальные люди.
Не, так не пойдёт )
Уже поздно выкидывать, да и нравится мне эта орм

p.s. А как нормальные люди поступают при изменении объекта (таблицы)?
Переписываете все sql запросы?
0
Эксперт .NET
 Аватар для Usaga
14731 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,857
19.03.2021, 05:46
Цитата Сообщение от Катафалк Посмотреть сообщение
Выкинуть нафиг linq2db (как и любую другую ОРМ) и делать все ручками конечно же. Как все нормальные люди.
Не лезьте в тему, в которой не разбираетесь. Пожалуйста.

Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Но выполнять код в using(var db..) не всегда есть возможность.
Вот это ключевой момент. Если нет возможности выполнить запрос, то и контекст создавать не надо.

Вообще, как в реальных проектах делается? Подключение к базе создаётся только на время, когда оно реально нужно. Когда оно перестаёт быть нужным (даже временно), оно закрывается. Я не знаю, что за приложение у вас. Вы можете полагаться как на DI и получать в свои сервисы инжектированный экземпляр DbContext, который задиспозится при выходе из области видимости (окончание запроса в веб-приложении, закрытии последнего окна в настольном или остановка сервиса, если у вас служба).

Если DI не используется и контекст вы руками создаёте (а так и есть, судя по всему), то можете создавать и диспозить (using) контексты по мере надобности.

Ну или, если у вас всё в один поток работает, создать один контекст и держать его до победного, ибо у Linq2Db нет никаких кешей контекста, которые бы забивались мусором во время работы. Единственный ОЧЕНЬ важный момент: в конструкторе контекста обязательно нужно указать, что не нужно удерживать открытым подключение.

C#
1
2
3
4
5
6
7
8
public class DB : LinqToDB.Data.DataConnection
{
    public DB(string connectionString)
        : base(LinqToDB.ProviderName.MySql, connectionString)
    {
        (this as IDataContext).CloseAfterUse = true;
    }
}
Это будет жизненно необходимо, если вы будете держать один контекст очень долго и использовать транзакции.

Добавлено через 37 секунд
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
p.s. А как нормальные люди поступают при изменении объекта (таблицы)?
Переписываете все sql запросы?
Этот чувак никак не поступает. Он к этим вещам вообще отношения не имеет. Иначе было бы что сказать по делу.

Добавлено через 9 минут
Цитата Сообщение от Катафалк Посмотреть сообщение
Выкинуть нафиг linq2db (как и любую другую ОРМ) и делать все ручками конечно же. Как все нормальные люди.
Внезапно, вопрос ТСа был про удержание открытым подключения к базе. А этот момент к ORM отношения не имеет и точно так же встаёт и при "делать всё ручками". Вы, как дофига "специалист", это должны понимать, раз сюда пришли со своими советами очень ценными.
2
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
19.03.2021, 08:44  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Ну или, если у вас всё в один поток работает, создать один контекст и держать его до победного
Вот так и было. Однопоток, и один контекст.
Но при длительном неиспользовании MySQL со своей стороны закрывает соединение.

Цитата Сообщение от Usaga Посмотреть сообщение
(this as IDataContext).CloseAfterUse = true;
То есть вот это не даст отключить соединение для MySQL?
Я попробовал на короткой дистанции, но не пойму как оно работает, поэтому и спрашиваю.

Если использовать БД SQLite то вот этот код (this as IDataContext).CloseAfterUse = true; я так понимаю использовать не нужно, так как sqlite не отключает ничего?
Цитата Сообщение от Usaga Посмотреть сообщение
Это будет жизненно необходимо, если вы будете держать один контекст очень долго
Да вот так и хотелось.
Наверное не правильно, но очень удобно, создать подключение к бд в начале выполнения, проверить корректность, и уже потом дёргать когда нужно, без нагромождений using и т.д.

p.s. Создание объекта через наследование DataConnection указано в wiki.
Нужно использовать IDataContext?
0
 Аватар для IamRain
4695 / 2702 / 735
Регистрация: 02.08.2011
Сообщений: 7,236
19.03.2021, 09:01
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Если использовать БД SQLite то вот этот код (this as IDataContext).CloseAfterUse = true; я так понимаю использовать не нужно,
Нужно. Зачем держать подключение открытым, даже когда вы не выполняете запросы?
BeginnerCoderCS, почитайте книги что-ли по ADO.NET. У IDbConnection следующая философия - открывать подключение как можно позже, и закрывать как можно раньше. То же самое, очевидно, касается любых надстроек сверху, включая Linq2Db.

Добавлено через 2 минуты
Вы с утра, перед тем как идти на работу/учебу, чистите зубы, умываетесь и оставляете кран открытым?
А после приходите, закрываете. Я верно понял?
3
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
19.03.2021, 09:14  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Вы с утра, перед тем как идти на работу/учебу, чистите зубы, умываетесь и оставляете кран открытым?
А после приходите, закрываете. Я верно понял?

Но я бы не стал сравнивать это с реальной жизнью.
Хотя с компьютером в принципе так и есть. Выключается крайне редко ))

Цитата Сообщение от IamRain Посмотреть сообщение
У IDbConnection следующая философия - открывать подключение как можно позже, и закрывать как можно раньше.
На подключение нужно дополнительное время.
После создания подключения первый запрос длится до 1.5 секунд (как я замечал), но все последующие работают намного быстрее.
Вот и получается что 10 запросов отдельными подключениями будут 15 секунд
или если одним подключением, то грубо 4 секунды.
0
 Аватар для IamRain
4695 / 2702 / 735
Регистрация: 02.08.2011
Сообщений: 7,236
19.03.2021, 09:20
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
На подключение нужно дополнительное время.
Быть может, при первом подключении - ну это IO-операция, все они этим грешат.
А для всех последующих был придуман пул подключений.
Надеюсь я вправил вам слегка представление о вещах этой аналогией.
Все как в жизни, индустрия разработки уже давно придумала best practices на многие однозначные проблемы, все что вам нужно - следовать им и все.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.03.2021, 09:20

Linq2db как изменить имя таблицы?
При описании класса таблицы атрибутом указывается имя таблицы. Например: //Здесь указывается имя таблицы public partial...

Запрос linq2db c условием разницы времени
Здравсвуйте) Испльзую орм linq2db. И у меня такой запрос: найти заказы которые выполнялись более одного дня orders = (from s in orders...

Как мне понастроить linq2db в .NET Core?
Зашёл в документацию по подключению к базе данных. Это сделал. public class ConnectionStringSettings : IConnectionStringSettings { ...

Как сохранить изменения сделанные в DataGridView в БД при использовании linq2db?
Заполнить dataGridView у меня получилось: using (DBSystem dbSystem = new DBSystem()) { bindingSource1.DataSource =...

linq2db.mysql - No PK is defined or all fields are keys при обновлении строки из формы
Приветствую Всех форумчан!!! Пытаюсь разобраться с linq2db, не могу понять следующее. есть вот такая табличка: CREATE TABLE...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru