Модератор
Эксперт .NET
15462 / 10707 / 2786
Регистрация: 21.04.2018
Сообщений: 31,521
Записей в блоге: 2
1

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

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

Author24 — интернет-сервис помощи студентам
Тема из цикла Готовые решения, примеры и рекомендации начинающим на 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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
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 Тема создана как...

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

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

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

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

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

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

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

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

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Осталось только разобраться с верификацией перед внесением изменений.
Это же должна быть одна транзакция: блокировка БД, верификация, изменение, снятие блокировки.
Надо разобраться как это делает SQLite.
Что за верификация и для чего?
1
Модератор
Эксперт .NET
15462 / 10707 / 2786
Регистрация: 21.04.2018
Сообщений: 31,521
Записей в блоге: 2
11.02.2020, 11:43  [ТС] 45
Цитата Сообщение от Usaga Посмотреть сообщение
Что за верификация и для чего?
Что за время редактирования другим пользователем эти данные не были изменены.
Если были изменены, то нужно дополнительное подтверждение для записи.
0
Эксперт .NET
12061 / 8370 / 1280
Регистрация: 21.01.2016
Сообщений: 31,562
11.02.2020, 12:34 46
Элд Хасп, c EF это делается ТОЛЬКО через Concurrency Token. Других нормальных возможностей с этой ORM у вас нет.
1
Модератор
Эксперт .NET
15462 / 10707 / 2786
Регистрация: 21.04.2018
Сообщений: 31,521
Записей в блоге: 2
11.02.2020, 17:21  [ТС] 47
Цитата Сообщение от Usaga Посмотреть сообщение
c EF это делается ТОЛЬКО через Concurrency Token. Других нормальных возможностей с этой ORM у вас нет.
Мой опыт работы с БД устарел лет на 30.
Буду вникать потихоньку.

Добавлено через 38 минут
Usaga, а в самой базе надо что-то добавлять для этого?
0
Эксперт .NET
12061 / 8370 / 1280
Регистрация: 21.01.2016
Сообщений: 31,562
12.02.2020, 06:48 48
Цитата Сообщение от Элд Хасп Посмотреть сообщение
а в самой базе надо что-то добавлять для этого?
Если в виде токена выступает уже существующее поле, то ничего не надо добавлять. В противном случае, добавлять надо. В SQL Server для этого есть специальный тип Rowversion\Timestamp (ничего общего со временем, просто автоматический счётчик), в Postgres есть скрытое поле xmin (номер транзакции внёсшей изменение). А что там в SQLite для этих целей подходит я не скажу. Но дата почти наверняка не подойдёт, ибо не хватит разрешающей способности (две команды на обновление могут прийти в одну миллисекунду).
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
27.05.2020, 20:45 49
Цитата Сообщение от Элд Хасп Посмотреть сообщение
/// <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
15462 / 10707 / 2786
Регистрация: 21.04.2018
Сообщений: 31,521
Записей в блоге: 2
27.05.2020, 21:04  [ТС] 50
Цитата Сообщение от Alessey Посмотреть сообщение
Ваш, скачанный с гитХаб ошибок не пишет, а мой весь в ошибках( В чем может быть причина?
Моё Решение для Framework. ваше для Standard.
Не знаю насколько это влияет.

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

Добавлено через 1 минуту
Насколько помню, проекты Framework видят Standard сборки, а наоборот - нет.
1
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
27.05.2020, 21:09 51
Цитата Сообщение от Элд Хасп Посмотреть сообщение
У вас часть на Standard, часть на Framework.
Ого! Что то гдето не туда ткнул. Вроде одно исправил, думал что везде FW осталось) Огромное спасибо! Ща переделывать буду)
0
Модератор
Эксперт .NET
15462 / 10707 / 2786
Регистрация: 21.04.2018
Сообщений: 31,521
Записей в блоге: 2
27.05.2020, 21:27  [ТС] 52
У 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
15462 / 10707 / 2786
Регистрация: 21.04.2018
Сообщений: 31,521
Записей в блоге: 2
27.05.2020, 21:32  [ТС] 53
Цитата Сообщение от Alessey Посмотреть сообщение
Так же не понял, зачем еще VM классы создавать. Уж если для XML свои классы, для БД тоже наверное свои потом будут. Почему же DTO (который хранится в памяти) сразу INPC не поддерживают?
Потому, что когда экземпляр класса "ушёл" из Модели она теряет контроль над ним.
И если потом во вне в этом экземпляре что-то изменится, то у Модели нет инструментов узнать об этом.
В результате может получится, что объект хранящийся в Модели имеет не те значения которые по мнению Модели там должны быть.
Это потенциальная дорога к багам.

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

Добавлено через 2 минуты
По сути такое использование DTO типов проистекает из правил SOLID.
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
27.05.2020, 21:37 54
Заработало. Я уж опечалился. Копался копался, а в итоге до самого интересного мог и не дойти)
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как сделать данную задачу ещё проще... не знаю.
По сути я её писал и сам по ходу продолжал изучение.
Это как бы не сколько учебник, а "записи с передовой".
Это понятно.
Вы меня спасли, буду дальше печатать и копаться) Может чего прояснится к концу проекта)
0
Модератор
Эксперт .NET
15462 / 10707 / 2786
Регистрация: 21.04.2018
Сообщений: 31,521
Записей в блоге: 2
27.05.2020, 21:40  [ТС] 55
По сути такое использование DTO типов проистекает из правил SOLID.
Цитата Сообщение от Alessey Посмотреть сообщение
буду дальше печатать и копаться) Может чего прояснится к концу проекта)
Удачи!
Будут проблемы - не стесняйтесь обращаться.
Лучше сто раз спросить, чем сделать один раз неправильно.
0
27.05.2020, 21:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.05.2020, 21:40
Помогаю со студенческими работами здесь

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

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

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

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

Обсуждение темы "Библиотека элементов для реализации WPF MVVM Решений" [WPF, Элд Хасп]
Любое обсуждение, рекомендации, вопросы и т.п. по теме...

Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп]
В этой теме перечень полезных тем для начинающих. Обсуждение введите в самих темах. Для включения...


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

Или воспользуйтесь поиском по форуму:
55
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru