Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.78/573: Рейтинг темы: голосов - 573, средняя оценка - 4.78
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2

Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп]

30.12.2019, 12:08. Показов 112950. Ответов 54

Студворк — интернет-сервис помощи студентам
Тема из цикла Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп]

Создана как продолжение темы WPF, DataGridComboBoxColumn (привязка к ObservableCollection и чтение из файла) от Valius.

Цитата Сообщение от Valius Посмотреть сообщение
Цитата Сообщение от Элд Хасп
Далее переходим к созданию XAML.
Задаём корневой тег, допустим, StudentRooms
В нём два вложенных.
Один для общежитий Dormitories, второй для комнат Rooms.
Каждое общежитие представлено тегами Dormitory с атрибутами ID, название и адрес.
Если задумывается в будущем изменение каких-то атрибутов (кроме ID), то внутри тега надо создать коллекцию истории его изменения.
Каждая комната представлена тегом Room с атрибутами ID, номер, ID общежития и возможно ещё дополнительные теги.
С историей изменений - по необходимости.
Чес сказать, нифига не понял, как это, где это
Задаём корневой тег, допустим, StudentRooms
далее тоже не догнал.
Цитата Сообщение от Элд Хасп
Создаём в редакторе соответствующий XML файл с тестовыми данными. По этому файлу средствами Студии создаём классы для десериализации.
Хм... Тоже не понятно. Мы что, сначало как-то формируем XML, а уже снего создаем класс в шарпе, который будем сериализавать/десериализовать? Что это как-то не то, вроде бы.
Цитата Сообщение от Элд Хасп
далее переходим к интерфейсу Модели.
...
Для работы с общежитиями.
Метод возвращающий список общежитий.
Метод удаляющий общежитие из списка.
Метод добавляющий общежитие из списка.
Метод изменяющий данные об общежитие.
Событие уведомляющее об любых изменениях в списке общежитий.......
Разве все это не делает сама view? в datagrid.
Ведь в модели мы только записываем/считываем предоставленные данные для самой datagrid.



Цитата Сообщение от Элд Хасп
После этого можно переходить к созданию Модели реализующей этот интерфейс и работающей с XML.
ViewModel будет работать с Моделью через интерфейс. И если в будущем потребуется изменить хранилище на базу, то просто будет создана Модель с этим же интерфейсом, но работающая с Базой. И изменения больше ничего не затронут.
И в итоге чет вообще запутался((
2
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.12.2019, 12:08
Ответы с готовыми решениями:

Пример создания приложения для тестирования [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Пример практической реализации приложения для тестирования...

DynamicResource с привязываемым ключом на примере локализации приложения [WPF, Элд Хасп, DynamicResourceBinding]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Необходимость изменения ключа (извлекаемого ресурса) из...

Создание приложения "Штатное Расписание" в паттерне MVVM [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Тема создана как продолжение темы...

54
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
11.02.2020, 10:14  [ТС]
Студворк — интернет-сервис помощи студентам
Usaga, я обдумал вариант с раздельным хранением истории.
И как-то тоже не пришёл в голову вариант, как обойти возможное нарушение в таблице Person указана одна комната, а в истории последней записью идёт другая.
Думал, сделать вместо Person.RoomID - ID записи из истории, но тоже нет гарантии, что этот ID будет указывать на последнюю запись.

Алгоритмически самый верный вариант, как вы и сказали, это брать последнюю (по времени) запись в истории.
Для удобства, наверное, надо отсортировать записи в истории по PersonID и Timestamp (по убыванию). И тогда выбирать первую (FirstOrDefault) по PersonID запись из истории.

Что касается многопользовательской работы, то SQLite её поддерживает, судя по документации.
Экспериментально пока не проверил.
0
Эксперт .NET
 Аватар для Usaga
14821 / 9605 / 1369
Регистрация: 21.01.2016
Сообщений: 36,158
11.02.2020, 10:17
Цитата Сообщение от Элд Хасп Посмотреть сообщение
И как-то тоже не пришёл в голову вариант, как обойти возможное нарушение
Это техническая возможность такого нарушения) Понятно, что вы можете озадачиться и реализовать корректное поведение, которое не даст такому случиться. Но возможность такой ошибки в будущем данной схемой базы не исключается. А как сказал однажды Мёрфи... Ну вы поняли)

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Для удобства, наверное, надо отсортировать записи в истории по PersonID и Timestamp (по убыванию). И тогда выбирать первую (FirstOrDefault) по PersonID запись из истории.
Не надо. Я ранее упоминал про составной индекс включающий оба этих поля. Он как раз для этой цели. Точнее, в запросе нужно будет указать сортировку и TOP 1 (или как оно там в SQLite), но с наличием индекса такой сортировки, по сути, не произойдёт, а будет взята крайняя запись в дереве индекса.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Что касается многопользовательской работы, то SQLite её поддерживает, судя по документации.
Экспериментально пока не проверил.
Поддерживает блокировкой всей базы целиком с помощью Lock-файла или как-то так. Т.е. это ни разу не то, что могут "взрослые" СУБД. Но SQLite таковым и не позиционируется.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
11.02.2020, 10:47  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Поддерживает блокировкой всей базы целиком с помощью Lock-файла или как-то так.
Да, на время изменения (транзакции?), как я понял.
У "взрослых" блокируется только изменяемые записи.
Для БД без сервера по другому, наверное, и не сделаешь.

Осталось только разобраться с верификацией перед внесением изменений.
Это же должна быть одна транзакция: блокировка БД, верификация, изменение, снятие блокировки.
Надо разобраться как это делает SQLite.
0
Эксперт .NET
 Аватар для Usaga
14821 / 9605 / 1369
Регистрация: 21.01.2016
Сообщений: 36,158
11.02.2020, 10:49
Цитата Сообщение от Элд Хасп Посмотреть сообщение
У "взрослых" блокируется только изменяемые записи.
Там всё сложнее. Уровень и "сила" блокировок сильно зависят от типа запроса и уровня изоляции транзакции. Сложная тем, на самом деле.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Осталось только разобраться с верификацией перед внесением изменений.
Это же должна быть одна транзакция: блокировка БД, верификация, изменение, снятие блокировки.
Надо разобраться как это делает SQLite.
Что за верификация и для чего?
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
11.02.2020, 11:43  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Что за верификация и для чего?
Что за время редактирования другим пользователем эти данные не были изменены.
Если были изменены, то нужно дополнительное подтверждение для записи.
0
Эксперт .NET
 Аватар для Usaga
14821 / 9605 / 1369
Регистрация: 21.01.2016
Сообщений: 36,158
11.02.2020, 12:34
Элд Хасп, c EF это делается ТОЛЬКО через Concurrency Token. Других нормальных возможностей с этой ORM у вас нет.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
11.02.2020, 17:21  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
c EF это делается ТОЛЬКО через Concurrency Token. Других нормальных возможностей с этой ORM у вас нет.
Мой опыт работы с БД устарел лет на 30.
Буду вникать потихоньку.

Добавлено через 38 минут
Usaga, а в самой базе надо что-то добавлять для этого?
0
Эксперт .NET
 Аватар для Usaga
14821 / 9605 / 1369
Регистрация: 21.01.2016
Сообщений: 36,158
12.02.2020, 06:48
Цитата Сообщение от Элд Хасп Посмотреть сообщение
а в самой базе надо что-то добавлять для этого?
Если в виде токена выступает уже существующее поле, то ничего не надо добавлять. В противном случае, добавлять надо. В SQL Server для этого есть специальный тип Rowversion\Timestamp (ничего общего со временем, просто автоматический счётчик), в Postgres есть скрытое поле xmin (номер транзакции внёсшей изменение). А что там в SQLite для этих целей подходит я не скажу. Но дата почти наверняка не подойдёт, ибо не хватит разрешающей способности (две команды на обновление могут прийти в одну миллисекунду).
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
27.05.2020, 20:45
Цитата Сообщение от Элд Хасп Посмотреть сообщение
/// <summary>Класс VM для общежитий работающий с DTO типом DormitoryDTO</summary>
    public class DormitoryVM : BaseIdVM<DormitoryDTO>, ICopy<DormitoryVM>, IEquatableValues<DormitoryVM>
    {
Который день перепечатываю ваш проект в ручную, сегодня встрял в этом месте. VS не хочет видеть другие проекты в решении((( Ваш, скачанный с гитХаб ошибок не пишет, а мой весь в ошибках( В чем может быть причина?
в VMClasses скопипастил даже 2 класса, ничего не помогает( Папку кэша проекта чистил, не помогает. Копирую из этой статьи, в вашем проекте на гитхаб есть отличия, но я до них не дошел еще.
И сразу несколько непонятных для меня вопросов)
Как я понял, DTO - это общий класс, хранимый в памяти.
XML - классы нужны для сериализации/десериализации XML.
Почему не сделать сразу класс, который можно сериализовать в XML? Очень сильно запутался, как такую логику только продумать можно, не то что реализовать...
Так же не понял, зачем еще VM классы создавать. Уж если для XML свои классы, для БД тоже наверное свои потом будут. Почему же DTO (который хранится в памяти) сразу INPC не поддерживают?
Мой проект:
https://github.com/Kozlov-AE/StudentRooms
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
27.05.2020, 21:04  [ТС]
Цитата Сообщение от Alessey Посмотреть сообщение
Ваш, скачанный с гитХаб ошибок не пишет, а мой весь в ошибках( В чем может быть причина?
Моё Решение для Framework. ваше для Standard.
Не знаю насколько это влияет.

Добавлено через 2 минуты
Alessey, даже не так.
У вас часть на Standard, часть на Framework.

Добавлено через 1 минуту
Насколько помню, проекты Framework видят Standard сборки, а наоборот - нет.
1
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
27.05.2020, 21:09
Цитата Сообщение от Элд Хасп Посмотреть сообщение
У вас часть на Standard, часть на Framework.
Ого! Что то гдето не туда ткнул. Вроде одно исправил, думал что везде FW осталось) Огромное спасибо! Ща переделывать буду)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
27.05.2020, 21:27  [ТС]
У ICopy нет public
C#
11
public interface ICopy<T>
Добавлено через 53 секунды
Тоже самое у IEquatableValues

Добавлено через 8 минут
Цитата Сообщение от Alessey Посмотреть сообщение
Как я понял, DTO - это общий класс, хранимый в памяти.
Это контейнер для данных: Data Transfer Object.
В концепции MVVM на уровне Model в основном применяются иммутабельные DTO.

Добавлено через 1 минуту
Цитата Сообщение от Alessey Посмотреть сообщение
XML - классы нужны для сериализации/десериализации XML.
Почему не сделать сразу класс, который можно сериализовать в XML?
Вопрос удобства и привычки.
Мне удобнее сначала создать структуру данных (XML файл ил БД), а потом нужные под неё классы.

Добавлено через 4 минуты
Цитата Сообщение от Alessey Посмотреть сообщение
Очень сильно запутался, как такую логику только продумать можно, не то что реализовать...
Согласен.
Порог вхождения для этого примера выше чем для только начинающих на C#.
Он рассчитан уже на тех кто хорошо ориентируется в C#, в ООП, имеет начальное представление о шаблонах проектирования приложений, более менее освоил базис WPF.
Для более начального уровня, есть примеры других приложений по ссылке в подписи моего поста.

Как сделать данную задачу ещё проще... не знаю.
По сути я её писал и сам по ходу продолжал изучение.
Это как бы не сколько учебник, а "записи с передовой".
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
27.05.2020, 21:32  [ТС]
Цитата Сообщение от Alessey Посмотреть сообщение
Так же не понял, зачем еще VM классы создавать. Уж если для XML свои классы, для БД тоже наверное свои потом будут. Почему же DTO (который хранится в памяти) сразу INPC не поддерживают?
Потому, что когда экземпляр класса "ушёл" из Модели она теряет контроль над ним.
И если потом во вне в этом экземпляре что-то изменится, то у Модели нет инструментов узнать об этом.
В результате может получится, что объект хранящийся в Модели имеет не те значения которые по мнению Модели там должны быть.
Это потенциальная дорога к багам.

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

Добавлено через 2 минуты
По сути такое использование DTO типов проистекает из правил SOLID.
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
27.05.2020, 21:37
Заработало. Я уж опечалился. Копался копался, а в итоге до самого интересного мог и не дойти)
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как сделать данную задачу ещё проще... не знаю.
По сути я её писал и сам по ходу продолжал изучение.
Это как бы не сколько учебник, а "записи с передовой".
Это понятно.
Вы меня спасли, буду дальше печатать и копаться) Может чего прояснится к концу проекта)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16445 / 11288 / 2892
Регистрация: 21.04.2018
Сообщений: 33,189
Записей в блоге: 2
27.05.2020, 21:40  [ТС]
По сути такое использование DTO типов проистекает из правил SOLID.
Цитата Сообщение от Alessey Посмотреть сообщение
буду дальше печатать и копаться) Может чего прояснится к концу проекта)
Удачи!
Будут проблемы - не стесняйтесь обращаться.
Лучше сто раз спросить, чем сделать один раз неправильно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.05.2020, 21:40

Библиотека элементов для реализации WPF MVVM Решений [WPF, Элд Хасп]
Решил собрать элементы используемые в темах в этом разделе. В библиотеку включаю элементы которые, на мой взгляд, имеют универсальное...

WPF команды и MVVM. Часть 1. [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Для использования и создания WPF команд в Net предусмотрен...

WPF конвертеры [Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html View получает данные от ViewModel, но часто бывают случаи...

WPF vs WinForms (для начинающих) [Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Эту тему решил создать, так как очень часто сталкиваюсь с...

Элемент геометрии «Стрелка» [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Реализация сделана по вопросу отDissolve в теме...


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

Или воспользуйтесь поиском по форуму:
55
Ответ Создать тему
Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru