Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34

Создание программы - ООП модель, MVP

30.10.2018, 11:10. Показов 70535. Ответов 99

Студворк — интернет-сервис помощи студентам
Пример разработки приложения с нуля под WinForms

Рассматриваются такие аспекты разработки как:
  • Создание ООП модели предметной области.
  • Разработка Unit-тестов.
  • Архитектура приложения под WinForms.
  • Разработка пользовательского интерфейса с разделением модели и представления (MVP).
  • Разработка UserControl для построения пользовательского интерфейса.
  • Рефакторинг, непрерывная интеграция.
  • Организация проекта в VisualStudio.

В этом примере НЕ рассматриваются шаблоны типа фабрик, не рассматривается внедрение зависимостей (DI).
Используется простой вариант шаблона Model-View-Presenter, адаптированный под специфику WinForms.

Этот топик перекликается с этим FAQ, и является практическим примером к нему.
Комментарии и вопросы - приветствуются.

Постановка задачи

Требуется создать приложение - опросник.

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

Приложение должно состоять из двух частей - конструктора опросника и приложения в котором респондент может ответить на вопросы готового опросника.

Результаты опроса должны выгружаться в виде, пригодном для дальнейшей обработки.
18
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.10.2018, 11:10
Ответы с готовыми решениями:

Встраивание Google RESTful pattern A в модель MVP
Доброго дня. Всем известна модель MVC и её разновидность MVP, достаточно подробную статью по реализации MVP можно посмотреть здесь А...

Создание дочернего окна в MVP
Продолжаю разбираться с MVP. Не знаю, как правильно в данном шаблоне сделать работу с дочерним окном. Есть главное окно MainForm,...

ООП. Переделать фрагмент программы под ООП
Есть небольшой фрагмент из программы, который необходимо перестроить под ООП(создать класс), для удобного испольщования. Можно ли изменить...

99
 Аватар для агерон
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
03.11.2018, 19:02
Студворк — интернет-сервис помощи студентам
Печальный код, уровень 3 ну может 4 курса IT специальности + тесты ни о чем
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
03.11.2018, 19:13  [ТС]

Не по теме:

umatkot, Стесняюсь спросить, это вы под тяжелыми наркотиками все пишите ? :D



Добавлено через 1 минуту
Цитата Сообщение от агерон Посмотреть сообщение
Печальный код, уровень 3 ну может 4 курса IT специальности + тесты ни о чем
Ну хорошо хоть до 4 курса дотянул
1
187 / 100 / 19
Регистрация: 15.09.2011
Сообщений: 801
03.11.2018, 19:44
Storm23, да, я сейчас под тяжелыми наркотиками. могу только отвечать. Не стесняйтесь, спрашивайте.

Добавлено через 3 минуты

Не по теме:

Storm23, я диплом сдал на 5, так что меня нет смысла тролить. учился я и учусь до сих пор. шаблоны я не учил - они мне не интересны. просто, если есть задача - я тупо её рашаю. Решаю так, как она должна работать. Я во Владивостоке и у меня уже просто 2:23 и мне не особо охота сочинять в данный момент и всё.



Добавлено через 1 минуту

Не по теме:

Storm23, с утреца, на свежую голову просмотрю код и добавлю что требуется



Добавлено через 8 минут
Цитата Сообщение от Storm23 Посмотреть сообщение
Печальный код, уровень 3 ну может 4 курса IT специальности + тесты ни о чем
тесты тестами, а код хороший, зря вы так

Добавлено через 2 минуты
в реале код идеален, я не вижу там пока дубости, если внуки мои посмотрят и посмеются - я не буду их ругать, но он пишет намного лучше меня - не знаю - для демонстрации или по привычке, но я так не делаю 0

Добавлено через 8 минут
Цитата Сообщение от Storm23 Посмотреть сообщение
Так, что бы номера вопросов постоянно шли подряд, даже если пользователь их перемешал или удалил.
Последний
Есть ли смысл поддерживать идею автора и делать дерево вопросов?
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
03.11.2018, 19:59  [ТС]
Цитата Сообщение от umatkot Посмотреть сообщение
Есть ли смысл поддерживать идею автора и делать дерево вопросов?
Что значит поддерживать? Нужно найти модель, которая максимально подходит под предметную область.
Я не вижу необходимости в дереве. Если вопросы повторяются (а это так, посмотрите примеры автора той темы), то это уже не дерево а граф. А реализовывать граф в такой программе - наверное можно, но неудобно ни для пользователя ни для программиста. Тем более, что разветвления графа все равно придется писать с условиями. Такими же как и в моем варианте. Только вот мой вариант линейный, и потому намного проще.
0
#MRoose
 Аватар для MIRAMIX
8 / 9 / 3
Регистрация: 22.02.2013
Сообщений: 416
05.11.2018, 19:49
Storm23, umatkot, давно не пишу, вот только сел за копипаст)
Код просто шедевр!!! Я просто в ступоре был еще в тот день. Все очень заплетено, сложно сходу в голове построить всю иерархию классов, постепенно буду переваривать по кусочкам код.
В одном проекте решили мою задачу, которую я бы вряд-ли решил, так еще таким образом, и показали, что такое UserControl (о кот-м я не знал ранее).
Просто человеческое спасибо.

Очень поражен таким подходом к ТЗ, хотелось бы узнать Ваш путь к таким познаниям. Уверен, книжки этому не научат.

Моя идея (от незнания) дерева неактуальна полностью. Это в сто раз круче. Правда в дальнейшем, когда переварю (а не скопипастю), вместо нажатия на далее, можно попробовать встроить переход в событие comboBox-а. Но это так, мысли вслух.

За старание и огромную помощь не против и ящика с пивом)

Добавлено через 22 минуты
Storm23, один вопрос пока - зачем в проекте опросника OpenFolderDialog.cs?
Вроде не вижу связи с другими классами.
Помидорами сразу не бросайтесь плиз)
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
05.11.2018, 21:06  [ТС]
Цитата Сообщение от MIRAMIX Посмотреть сообщение
Просто человеческое спасибо.
Да пожалуйста, это было не сложно.
Цитата Сообщение от MIRAMIX Посмотреть сообщение
зачем в проекте опросника OpenFolderDialog.cs?
Вроде не вижу связи с другими классами.
Это диалоговое окно появляется при указании папки с анкетами, для экспорта в CSV.
Можно было бы использовать стандартный FolderBrowserDialog, но он уродливый, мне не нравится. Поэтому, вместо него я использую OpenFolderDialog.
1
#MRoose
 Аватар для MIRAMIX
8 / 9 / 3
Регистрация: 22.02.2013
Сообщений: 416
06.11.2018, 01:55
Storm23, можно еще попрошу помощи?

Есть два .xlsx файла :
-первый содержит таблицу с ин-цией о сотрудниках (логин, ФИО, отдел и т.п.). По этому файлу будет определяться определение выдаваемого опросника
-второй с такой же таблицей, но только после прохождения опроса результаты будут вноситься в него.
Таблица почти аналогичная таблице из 1го файла.

Но самое интересное - после внесения данных о сотруднике (из таблицы из 1го файла) в заранее известные столбцы, сразу в пустые ячейки должны заноситься результаты прохождения опросника : ячейка с названием вопроса, следующая ячейка с ответом (если ручной ввод - то, что ввел пользователь, если с выбором ответа - текст выбранного варианта).

Проблем (уже, после вопросов на форуме опять же..) с чтением и записью (в таблицу) нет.
А вот как записать результаты не могу сообразить(

Записывать собирался так :
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
System.Data.OleDb.OleDbConnection MyConnection;
                System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
                MyConnection = new System.Data.OleDb.OleDbConnection(@"Provider=Microsoft.ACE.OleDb.12.0; data source=C:\Folder\b.xlsx;Extended Properties=Excel 12.0");
                MyConnection.Open();
                myCommand.Connection = MyConnection;
                myCommand.CommandText = "INSERT INTO [Лист1$](winlogin, rejim, grafik) VALUES('бла-бла','"+textBox1.Text+"','"+textBox2.Text+"');";
                myCommand.ExecuteNonQuery();
                MyConnection.Close();


Так понимаю, надо класс SevaLoader из QuestQore изменить, а именно :
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
public static void Save<T>(T obj, string filePath)
        {
            using (var fs = File.OpenWrite(filePath))
                new BinaryFormatter().Serialize(fs, obj);
        }


Еще в конструкторе есть экспорт в .csv. Его тоже просмотрел.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var ofd = new OpenFolderDialog();
            if (ofd.ShowDialog(this) == DialogResult.OK)
            {
                //получаем список анкет в выбранной папке
                var anketas = Directory.GetFiles(ofd.Folder, "*.a").Select(path => SaverLoader.Load<Anketa>(path)).ToList();
                if (anketas.Count == 0)
                {
                    MessageBox.Show("В этой папке не найдены анкеты");
                    return;
                }
 
                //запрашиваем имя выходного csv файла
                var sfd = new SaveFileDialog() {Filter = "CSV|*.csv"};
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    //экспортируем
                    new Export().ExportToCSV(anketas, sfd.FileName);
                    MessageBox.Show("Экспортировано " + anketas.Count + " анкет");
                }
            }


Но он записывает код (A1, A2..) вопроса и ответ под ним.
Еще ответ в таком виде - если ручной ввод, то выражение от пользователя, а если с выбором ответа - номер варианта из comboBox-а.

Подскажите, пожалуйста, как правильно изменить в классе код?

Если что, заранее также известен 1й свободный столбец после окончания таблицы.
0
 Аватар для агерон
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
06.11.2018, 03:26
Эххх студенты, хотел сперва довести рефакторинг этого проекта до конца, но раз такое дело выложу текущий вариант

Хоть посмотрите в каком направлении нужно двигаться
Вложения
Тип файла: zip QuestConstructor.zip (130.0 Кб, 64 просмотров)
0
 Аватар для агерон
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
06.11.2018, 03:29
в перспективе - глубокий рефакторинг + DI + вынос логики из UI+ адекватные тесты
но это ближе к следущей неделе
0
#MRoose
 Аватар для MIRAMIX
8 / 9 / 3
Регистрация: 22.02.2013
Сообщений: 416
06.11.2018, 10:04
агерон, это не по учебе))
деятельность на работе далека от написания кода (надеюсь так не останется). Как бы ТЗ дали на работе, но это чисто помощь в оптимизации.
Заинтригован, как приду изучу, спасибо)
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
06.11.2018, 10:53  [ТС]
Цитата Сообщение от агерон Посмотреть сообщение
Хоть посмотрите в каком направлении нужно двигаться
Из того, что я вижу, вы вынесли контролы в отдельный проект. Ок, приемлемо, но там контролы нигде не переиспользуются. Когда будут переиспользоваться, тогда и можно вынести.
Кроме того, вы добавили локализацию. Но зачем? Это приложение для локального использования. Усложнять его локализацией на мой взгляд совсем не нужно.

Цитата Сообщение от агерон Посмотреть сообщение
DI
Я в самом первом посте писал про то что не буду использовать DI. Это все таки обучающий пример среднего уровня.
Да и не нужно оно здесь.
Цитата Сообщение от агерон Посмотреть сообщение
Печальный код
Ну то есть, печальный код при добавлении локализации, и вынесении всего в папки становится профессиональным кодом, правильно?

Добавлено через 23 минуты
Цитата Сообщение от MIRAMIX Посмотреть сообщение
myCommand.CommandText = "INSERT INTO [Лист1$](winlogin, rejim, grafik) VALUES('бла-бла','"+textBox1.Text+"','"+textBox2.Tex t+"');";
Никогда нельзя вставлять текст в SQL запросы таким образом. Нужно использовать SqlParameter и передавать данные в запрос только через него.
Цитата Сообщение от MIRAMIX Посмотреть сообщение
Так понимаю, надо класс SevaLoader из QuestQore изменить, а именно :
Нет. Не нужно его менять. Это класс для бинарной сериализации. Не трогайте его.
Если нужен экспорт в другой формат, нужно написать еще один сервисный класс для экспорта и использовать его в нужном месте интерфейса.
Цитата Сообщение от MIRAMIX Посмотреть сообщение
Но он записывает код (A1, A2..) вопроса и ответ под ним.
Еще ответ в таком виде - если ручной ввод, то выражение от пользователя, а если с выбором ответа - номер варианта из comboBox-а.
Подскажите, пожалуйста, как правильно изменить в классе код?
Вообще-то я выше уже подробно объяснял (и не раз), почему не нужно использовать формулировки вопросов и альтернатив в качестве идентификаторов. Но я понял, что это неискоренимо
Также не нужно использовать эксель для таких вещей. Если пишется автоматизация чего либо, то нужно делать ее нормально - либо сохранять в БД и писать программку, которая будет строить результирующие таблички из БД, либо делать програмку просмотра заполненных анкет из файлов. Но эксель видимо тоже неискореним

Ок, сформулируйте задачу более подробно. Приведите примеры входных и выходных экселевских файлов.
Особенно поясните вот это:
Но самое интересное - после внесения данных о сотруднике (из таблицы из 1го файла) в заранее известные столбцы, сразу в пустые ячейки должны заноситься результаты прохождения опросника : ячейка с названием вопроса, следующая ячейка с ответом (если ручной ввод - то, что ввел пользователь, если с выбором ответа - текст выбранного варианта).
1
 Аватар для агерон
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
06.11.2018, 15:30
Storm23,
1 Локализация всегда не нужна ..... до тех пор пока не появляеться в ней потребность, но вот уже исправить тот вред статическими строками которые разбросанны по всему приложению за частую фактически не возможно, по этому чтобы не допускать подобных проблем в будущих боевых проектах на тестовых проекта нужно делать локализацию, чтобы выработать рефлекс
2) компонентный подход основа всего и вынос компонентов в отдельную библиотеку это правило хорошего тона + рефлекс
3) DI контейнер облегчает написание TDD&BDD тестов в будущем
4) печальный код так и остаеться печальным кодом, но если его провести через рефакторинг то он перестает таковым быть, сказал же что рефакторинг в процессе
5) Логика работы с компонентами прямо в обработчиках событий типа btOk_Click как я понимаю верх проффесионализма?
6) Это не обучающий пример среднего уровня - это попытка недоучившегося студента среднего уровня показать как он может в MVP, не переживай все такими были, у некоторых это проходит с опытом у некоторых нет

Добавлено через 9 минут
Storm23, Пойми твой код хорош, для студента 3-4 курса, для тестовой программы чтобы проверить рабочую идею. Скажу тебе даже больше..... зачастую для кода подобной тестовой программы даже не нужен GUI интерфейс, зачастую хватит CLI, т. к. реализация UI отвлекает от основного - реализации ядра системы и фиксации его поведения через TDD и BDD тесты

Теперь почему я не кинулся переписывать сразу ядро твоей программы...

Все просто примерно 30% логики ядра у тебя размазано по интерфейсу GUI, вот я и собераю все воедино + учти что у меня также есть основная работа и приоритет у нее выше
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
06.11.2018, 16:28  [ТС]
агерон
Ну я вас понял. С удовольствием изучу ваш опыт.

Цитата Сообщение от агерон Посмотреть сообщение
5) Логика работы с компонентами прямо в обработчиках событий типа btOk_Click как я понимаю верх проффесионализма?
В компонентах нет логики. Там есть вызов сервисных классов. Презентер я совмещаю с формой. Не вижу причин усложнять.
2
#MRoose
 Аватар для MIRAMIX
8 / 9 / 3
Регистрация: 22.02.2013
Сообщений: 416
07.11.2018, 01:31
Storm23, завтра уточню, что точно записывать в эксель.

Сейчас у меня проблемка - скопипастил, "вшил" ко своим окнам. Все хорошо, но вот контрол AlternativePanel не вылазит по нажатию на плюсик в QuestPanel. Сто раз сравнивал код. Все тоже самое.
Подозреваю на вот это в QuestPanel.Designer.cs :
Кликните здесь для просмотра всего текста
C#
1
2
this.pnAlternatives = new System.Windows.Forms.FlowLayoutPanel();
private System.Windows.Forms.FlowLayoutPanel pnAlternatives;

Вопрос - по идее Вы не лазили в подобные файлы, но откуда этот элемент взялся??
Он есть в Designer и все. На контроле нет элемента FlowLayoutPanel.

Объясните, пж, откуда он взялся?
Я от не знания эти 2 строчки вставил к себе в такие же места - не помогло.
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
07.11.2018, 09:15  [ТС]
Цитата Сообщение от MIRAMIX Посмотреть сообщение
Вопрос - по идее Вы не лазили в подобные файлы, но откуда этот элемент взялся??
Он есть в Designer и все. На контроле нет элемента FlowLayoutPanel.
Мне конечно трудно понять что вы делаете, но думаю, вы не все скопировали с формы. У панели pnAlternatives выставлен AutiSize, поэтому, когда в ней нет контролов, ее высота равна 0. Из-за этого ее не видно на форме.
Для того что бы ее увидеть на форме нужно:

1) Либо протянуть мышкой поверх формы, как для выделения нескольких элементов. И тогда все элементы внутри выделенной области станут видимыми:

2) Либо выделить ее в верхнем комбобоксе в окне Property:

3) Либо найти в главном меню панель Document Outline, отобразить ее, и найти в ней эту панель:

Вообще Document Outline лучше всего подходит если вы потеряли контрол или он затесался не туда куда нужно.
1
#MRoose
 Аватар для MIRAMIX
8 / 9 / 3
Регистрация: 22.02.2013
Сообщений: 416
10.11.2018, 01:20
Цитата Сообщение от агерон Посмотреть сообщение
Пойми твой код хорош, для студента 3-4 курса
ну не знаю, не знаю...код очень крутой, работает и тд и тп
куда и как лучше-то?)

Цитата Сообщение от Storm23 Посмотреть сообщение
Но эксель видимо тоже неискореним
да да) Эксель уже не моя задумка, без меня он был, есть и будет...

Цитата Сообщение от Storm23 Посмотреть сообщение
Вообще Document Outline лучше всего подходит если вы потеряли контрол или он затесался не туда куда нужно.
спасибо!!!!!! угораю тут, вписывал код, когда элементик-то был на форме. Все прекрасно теперь. И за Структура документа спасибо, удобная вещь, не знал)

Цитата Сообщение от Storm23 Посмотреть сообщение
Ок, сформулируйте задачу более подробно. Приведите примеры входных и выходных экселевских файлов.
Особенно поясните вот это:
Уточнил, каким должен быть выходной файл.

Вот изначальная табличка (могут быть еще столбцы/пропасть какие-то..)
Кликните здесь для просмотра всего текста


На выходе будет примерно такое :
Кликните здесь для просмотра всего текста


Опыт по работе с СУБД MySQL был, подсказка форумчан про OleDB решила много вопросов.
Только вот как заполненную анкету вписать во 2й эксель?

Суть такова - во 2м файле заранее будут столбцы с вопросами.
То есть, в опроснике мы создаем несколько вопросов A1,A2.... Так вот, в экселе после столбца id (мб еще столбец с ФИО добавим) будут столбцы с номерами вопросов. Для облегчения реализации, они будут созданы заранее.
Даже если вопрос A4 и A5 зависим от выбора в вопросе A3, ответ занесем только в столбец 4 или 5.

id-простой внутренний код какой-то, для других целей. Не воспринимайте серьезно). Но у каждого сотрудника он уникален.

Ответом должен быть текст из выпадающего списка или введенный текст (если вариант с ручным вводом).
С записью через SQL нет проблем, но как объединить с прохождением опросника не могу додуматься.

Еще вопрос - как Вы установили свойство Dock для FlowLayoutPanel в Fill на форме конструктора и при этом у Вас эта панелька под toolStrip-ом?
У меня при таком свойстве она на всю форму растягивается, включая toolStrip.
Спасибо
0
9037 / 2937 / 494
Регистрация: 05.10.2013
Сообщений: 7,963
Записей в блоге: 216
10.11.2018, 06:53
Есть разные виды тестирования. Я не знаю как правильно называются те тесты, которые работают напрямую с зависимостями, например, с файлами, базами данных, какими-то внешними API вызовами и т.д. Я интересуюсь только Unit-тестированием. В большей степени TDD, а ещё больше BDD, то есть когда Unit-тест пишется до тестируемого кода. Отличительная черта Unit-тестов в том что они должны работать изолировано от любых зависимостей. Изолированность достигается с помощью инжектирования зависимостей. В Unit-тестах эти инжектированные зависимости заменяют на Mock, Stub, Spy и т.д. Одним словом их называют Test Doubles. В C# одна из самых популярных библиотек для создания Test Doubles - это NSubstitute.

Хорошая книга по Unit-тестированию: The Art of Unit Testing, Second Edition with examples in C#
1
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
10.11.2018, 13:05  [ТС]
Шаг 11: Добавление экспорта в БД

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

Для этого напишем отдельный сервисный класс, который будет получать заполненную анкету и экспортировать ее в БД:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    /// <summary>
    /// Экспорт в базу данных
    /// </summary>
    public class ExportToDB
    {
        public string ConnectionString { get; set; } = @"Provider=Microsoft.ACE.OleDb.12.0; data source=C:\export.xlsx;Extended Properties=Excel 12.0";
        public string TableName { get; set; } = "Лист1$";
        public bool ExportAltTextInsteadOfCode { get; set; } = false;
 
        public void Export(Questionnaire questionnaire, Anketa anketa)
        {
            using (var conn = new OleDbConnection(ConnectionString))
            {
                //формируем список колонок
                var columnsList = string.Join(", ", questionnaire.Select(q => q.Id));
 
                //формируем список параметров
                var paramsList = string.Join(", ", questionnaire.Select(q => "@" + q.Id));
                var sql = string.Format("INSERT INTO [{2}]({0}) VALUES({1});", columnsList, paramsList, TableName);
 
                //создаем команду
                using (var command = new OleDbCommand(sql, conn))
                {
                    //инициализируем параметры значениями
                    foreach (var q in questionnaire)
                    {
                        var answer = anketa.FirstOrDefault(a => a.QuestId == q.Id);
                        var val = GetExportedAlternativeValue(q, answer);
                        command.Parameters.AddWithValue("@" + q.Id, val);
                    }
 
                    //исполняем SQL запрос
                    conn.Open();
                    command.ExecuteNonQuery();
                }
 
                conn.Close();
            }
        }
 
        private object GetExportedAlternativeValue(Quest quest, Answer answer)
        {
            if (answer == null) return null;
 
            if (ExportAltTextInsteadOfCode)
            {
                if (answer.Text != null)
                    return answer.Text;
                var alt = quest.FirstOrDefault(a => a.Code == answer.AlternativeCode);
                return alt?.Title;
            }
            else
            {
                return answer.ToString();
            }
        }
    }
И делаем вызов этого сервиса в обработчике кнопки окончания интервью:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
        private void btFinish_Click(object sender, EventArgs e)
        {
            //предлагаем сохранить анкету
            if (MessageBox.Show("Сохранить анкету?", "Сохранение анкеты", MessageBoxButtons.OKCancel) == DialogResult.OK)
            {
                if (SaveToDB)
                    //сохраняем анкету в БД
                    new ExportToDB().Export(questionnaire, anketa);
                else
                     ....
            }
            ....
        }
Обратите внимание, что мы не меняем уже существующий функционал программы, не трогаем уже созданные классы. Поскольку модель у нас полностью отделена от представления, и поскольку мы используем Anemic модель, то доработки приложения сводятся к написанию еще одного сервисного класса, и вызова его из интерфейса программы. Никаких других исправлений в код не требуется.

В результате получаем экспорт в базу данных, например в Excel:


Полный код проекта на этом этапе:
Вложения
Тип файла: zip QuestConstructor (2).zip (920.8 Кб, 62 просмотров)
1
#MRoose
 Аватар для MIRAMIX
8 / 9 / 3
Регистрация: 22.02.2013
Сообщений: 416
11.11.2018, 21:55
Storm23, спасибо, записывает куда надо.
Но одна проблемка - чтобы понять как что работает, запустил изначально Ваш проект из архива.
На фото результата выше вроде во 2м стобце текст выбора из comboBox, но у меня записывает его id (как и с экспортом в .csv ранее).
В чем может быть дело?
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
11.11.2018, 22:33  [ТС]
Цитата Сообщение от MIRAMIX Посмотреть сообщение
но у меня записывает его id (как и с экспортом в .csv ранее).
В чем может быть дело?
В экспортере есть свойство ExportAltTextInsteadOfCode, выставьте его в true.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.11.2018, 22:33
Помогаю со студенческими работами здесь

Модель ООП
Помоги сделать, пожалуйста работу! Возможно у кого нибудь есть примеры работы с классами! БУду рада всему, что есть! У меня тема...

Закрепить модель ООП
Добрый день. Ситуация такая: Я знаю и представляю себе модель ООП, классы, объекты, наследование и т.д. Но так как до чисто...

Модель работы светодиода ооп
здравствуйте, буду очень благодарна за хотя бы примерный код. никак не могу понять зачем тут использовать ооп примерный интерфейс

ООП модель системы спама
Срочно нужна помощь! Помогите пожалуйста реализовать программу с помощью классов. Спамер рассылает по сети Internet недобросовестную...

Ооп модель телефонного справочника
Нужен код на тему в заголовке с добавлением классов.Га с++ Буду очень благодарна!!


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

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

Новые блоги и статьи
YAFU@home — распределённые вычисления для математики. На CPU
Programma_Boinc 20.01.2026
YAFU@home — распределённые вычисления для математики. На CPU YAFU@home — это BOINC-проект, который занимается факторизацией больших чисел и исследованием aliquot-последовательностей. Звучит. . .
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru