powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Архитектура приложения
25 сообщений из 66, страница 1 из 3
Архитектура приложения
    #38570830
sadata
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветы.

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

Приложение - примитивный журнал документов. Входящие\исходящие, откуда и когда пришли краткое содержание etc

Итак, суть. Использую firebird + winforms.
Модель данных БД(2 таблицы):
1. T_DOC_TYPE //Типы документов
F_ID(PK) //ID
,F_NAME //Наименование
,F_DAY_TO_PERFORM //Дней до исполнения
,F_TO_ALARM //Дней до предупреждения

2. T_DOC //Документы
F_ID //ID
,F_DOC_TYPE(FK->T_DOCTYPE) //Тип документа
,остальные реквизиты документа

Хранимок и вьюх нет, есть по одному триггеру на таблицу для получения ID из сиквенса

С описанием БД закончил, теперь к приложеню)

Скрин главного окна для наглядности:

В меню справочники мы проваливаемся в окно для редактирования типов документов:

Есть еще одно маленькое окно для добавляения\редактирования типа документов в грид и в БД соответственно, потому что редактируемые гриды в приложении кажутся мне не кошерными

Теперь к коду

В коде форм ничего нету, кроме создания компоненов и обработчиков событий которые дергают все остальное в одну строчку
Есть 4 класса:
BindingINI, для чтения .ini файла в котором прописаны пути к БД и пути к шаблону отчетов .xls
Код: 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.
namespace DocRegister
{
    public class BindingINI
    {
        /*
         * Чтение .ini файла
         * Параметры:
         *      (key) ключ в .ini файле
         * Возвращает:
         *      (string) значениe ключа key
         *      (null) если ключа key нет
         */
        public static string readSetting(string key)
        {
            string line;
            StreamReader srFile = new StreamReader(@"DRConfig.ini");
            while ((line = srFile.ReadLine()) != null)
            {
                if (line.Contains(key))
                {
                    srFile.Close();
                    return line.Substring(key.Length);
                }
            }
            srFile.Close();
            return line;
        }
    }
}


BindingDB, для подключения к БД и работе с ней
Код: 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.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
namespace DocRegister
{
    public class BindingDB
    {
        /*
         * Создание строки подключения с БД
         * Возвращает:
         *      (string) строка подключения 
         */
        private static string GetConString()
        {
            FbConnectionStringBuilder ConString = new FbConnectionStringBuilder();
            ConString.UserID = "SYSDBA";
            ConString.Password = "masterkey";
            ConString.Database = BindingINI.readSetting("DataBasePatch=");
            ConString.ServerType = 0;
            return ConString.ToString();
        }

        /*
         * Создание соединения с БД
         * Возвращает:
         *      (Connection) соединение с БД
         *      (null) если строка подключения невалидна
         */
        private static FbConnection GetConnection()
        {
            try
            {
                return new FbConnection(GetConString());
            } catch (System.ArgumentException exp) 
            {
                MessageBox.Show(exp.ToString(),
                                "Ошибка соединения с БД",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return null;
            }
        }

        /*
         *  Получение данных из БД
         *  Параметры:
         *          (query) SQL запрос к БД
         *  Возвращает:
         *          (DataTable) результирующую таблицу SQL запроса
         *          (null) если не удалось подключится к БД или SQL запрос с ошибкой
         */
        public static DataTable GetTable(string query)
        {
            FbConnection connection = GetConnection();
            if (connection == null)
                return null;
            FbDataAdapter dAdapter = new FbDataAdapter(query, connection);
            DataSet dSet = new DataSet();
            try
            {
                dAdapter.Fill(dSet);
                return dSet.Tables[0];
            }
            catch (FbException exp) 
            {
                MessageBox.Show(exp.ToString(),
                                "Ошибка соединения с БД",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return null;
            }
        }

        /*
         *  Добавление\Изменение\Удаление данных из БД
         *  Параметры:
         *          (query) SQL запрос к БД
         *  Возвращает: 
         *          (string) параметр из запроса          
         *          (string) "success" если запрос был без параметра 
         *          (null) если не удалось подключится к БД или SQL запрос с ошибкой
         */
        public static string SetTable(string query)
        {
            FbConnection connection = GetConnection();
            if (connection == null)
                return null;
            try
            {
                FbCommand command = new FbCommand(query, connection);
                FbParameter parameter = new FbParameter();
                parameter.Direction = ParameterDirection.Output;
                FbParameter parameter1 = new FbParameter();
                parameter1.Direction = ParameterDirection.Output;
                command.Parameters.Add(parameter);
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
                if (command.Parameters[0].Value == null)
                    return "success";
                return command.Parameters[0].Value.ToString();
            }
            catch (FbException exp)
            {
                connection.Close();
                MessageBox.Show(exp.ToString(),
                                "Ошибка соединения с БД",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return null;
            }
        }

        /*
         * Создает резервную копию БД
         * с наименованием в формате "dd.MM.yyyy.HH.mm.ss"
         * в директории с БД
         */
        public static void CreateBackup()
        {
            string patchNameBackup = BindingINI.readSetting("DataBasePatch=");
            string patchBackup = patchNameBackup.Substring(0, patchNameBackup.LastIndexOf(@"\") + 1);
            string nameBackup = System.DateTime.Now.ToString("dd.MM.yyyy.HH.mm.ss");
            try
            {
                FbBackup backup = new FbBackup { ConnectionString = GetConString() };                
                backup.BackupFiles.Add(new FbBackupFile(patchBackup + nameBackup + ".gbk", 2048));
                backup.Verbose = true;
                backup.Options = FbBackupFlags.IgnoreLimbo;
                backup.Execute();
            }
            catch (FbException exp)
            {
                MessageBox.Show(exp.ToString(),
                                "Ошибка соединения с БД",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }
    }
}


DocType, класс Тип документа, имеет методы добавления, изменения, удаления, работает с классом BindingDB
Код: 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.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
namespace DocRegister
{
    public class DocumentType
    {
        private SqlInt32 docTypeID;    //ID вида документа
        private SqlString name;        //Наименование
        private SqlInt32 dayToPerform; //Дней на исполнение
        private SqlInt32 dayToAlarm;   //Дней до предупреждения

        /*
         * Инициализирует новый тип документа
         */
        public DocumentType(SqlString Name, SqlInt32 DayToPerform, SqlInt32 DayToAlarm)
        {
            this.name = Name;
            this.dayToPerform = DayToPerform;
            this.dayToAlarm = DayToAlarm;
        }

        /*
         * Инициализирует уже существующий тип документа
         */
        public DocumentType(SqlInt32 DocTypeID, SqlString Name, SqlInt32 DayToPerform, SqlInt32 DayToAlarm)
        {
            this.docTypeID = DocTypeID;
            this.name = Name;
            this.dayToPerform = DayToPerform;
            this.dayToAlarm = DayToAlarm;
        }

        /*
         * Удаляет тип документа из БД
         */
        public void Delete()
        {
            BindingDB.SetTable("DELETE\n" +
                               "FROM T_DOC_TYPE\n" +
                               "WHERE F_ID = " + this.docTypeID.Value);
        }

        /*
         * Обновляет тип документа в БД
         */
        public void Update()
        {
            BindingDB.SetTable("UPDATE T_DOC_TYPE\n" +
                               "SET F_NAME = '" + this.name.Value + "'\n" +
                               "   ,F_DAY_TO_PERFORM = " + this.dayToPerform.Value + "\n" +
                               "   ,F_DAY_TO_ALARM = " + this.dayToAlarm.Value + "\n" +
                               "WHERE F_ID = " + this.docTypeID.Value);
        }

        /*
         * Добавляет тип документа в БД
         */
        public void Insert()
        {
            this.docTypeID = SqlInt32.Parse(BindingDB.SetTable("INSERT INTO T_DOC_TYPE (F_NAME\n" +
                                                               "                       ,F_DAY_TO_PERFORM\n" +
                                                               "                       ,F_DAY_TO_ALARM)\n" +
                                                               "VALUES\n" +
                                                               "('" + this.name.Value + "'\n" +
                                                               "," + this.dayToPerform.Value + "\n" +
                                                               "," + this.dayToAlarm.Value + ")\n" +
                                                               "RETURNING F_ID"));
        }
        
        public SqlInt32 DocTypeID
        {
            get { return docTypeID; }
        }

        public SqlString Name
        {
            get { return name; }
            set { name = value; }
        }

        public SqlInt32 DayToPerform
        {
            get { return dayToPerform; }
            set { dayToPerform = value; }
        }

        public SqlInt32 DayToAlarm
        {
            get { return dayToAlarm; }
            set { dayToAlarm = value; }
        }

    }
}


DocTypeCollection, класс Коллекция типов документа, имеет методы добавления, изменения, удаления, работает с классом DocType
Код: 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.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
namespace DocRegister
{
    public class DocTypeCollection
    {
        private BindingList<DocumentType> docTypes; //Коллекция типов документов

        public BindingList<DocumentType> DocTypes
        {
            get { return docTypes; }
        }

        /*
         * Инициализирует коллекцию типов документов
         * запрос к БД, выборка всех типов
         */
        public DocTypeCollection() 
        {
            docTypes = new BindingList<DocumentType>();
            DataTable table = BindingDB.GetTable("Select F_ID\n" +
                                                 "      ,F_NAME\n" +
                                                 "      ,F_DAY_TO_PERFORM\n" +
                                                 "      ,F_DAY_TO_ALARM\n" +
                                                 "From T_DOC_TYPE");
            foreach (DataRow dr in table.Rows)
            {
                this.docTypes.Add(new DocumentType((SqlInt32)((int)dr.ItemArray[0]),
                                                   (SqlString)((string)dr.ItemArray[1]),
                                                   (SqlInt32)((int)dr.ItemArray[2]),
                                                   (SqlInt32)((int)dr.ItemArray[3])));
            }
        }

        /*
         * Поиск типа документа в коллекции
         * Параметры:
         *      (docTypeID) ID типа документа
         * Возвращает:
         *      (DocumentType) ссылку на найденный тип документа
         *      (null) если тип документа не найден
         */
        public DocumentType SearchDocType(SqlInt32 DocTypeID)
        {
            IEnumerable<DocumentType> ie = from dt in DocTypes
                                           where dt.DocTypeID.Equals(DocTypeID)
                                           select dt;
            List<DocumentType> l = new List<DocumentType>(ie);
            if (l.Count == 0)
                return null;
            return l[0];
        }

        /*
         * Удаляет тип документа из БД затем из коллекции
         * Параметры:
         *      (docTypeID) ID типа документа
         */
        public void DeleteDocType(SqlInt32 DocTypeID)
        {
            DocumentType foundDT = SearchDocType(DocTypeID);
            foundDT.Delete();
            docTypes.Remove(foundDT);
        }

        /*
         * Обновляет тип документа в коллекции затем в БД
         * Параметры:
         *      (docTypeID) ID типа документа
         *      (Name) новое наименование
         *      (DayToPerform) новое кол-во дней на исполнение
         *      (DayToAlarm) новое кол-во дней до предупреждения
         */
        public void UpdateDocType(SqlInt32 DocTypeID, SqlString Name, SqlInt32 DayToPerform, SqlInt32 DayToAlarm)
        {
            DocumentType foundDT = SearchDocType(DocTypeID);
            foundDT.Name = Name;
            foundDT.DayToPerform = DayToPerform;
            foundDT.DayToAlarm = DayToAlarm;
            foundDT.Update();
        }

        /*
         * Добавляет новый тип документа в БД затем в коллекцию
         * Параметры:
         *      (Name) Наименование типа документа
         *      (DayToPerfrom) Дней на исполнение документа
         *      (DayToAlarm) Дней до предупреждения
         */
        public void InsertDocType(SqlString Name, SqlInt32 DayToPerform, SqlInt32 DayToAlarm)
        {
            DocumentType newDocType = new DocumentType(Name, DayToPerform, DayToAlarm);
            newDocType.Insert();
            docTypes.Add(newDocType); 
        }

    }
}



Приложение пока что работает только с таблицей типов документов, но работа с самими документами я думаю будет аналогичной.
При запуске приложения и создании главной формы создается объект DocTypeCollection и загружает в себя все данные которые есть, далее по формам ходит только ссылка на объект DocTypeCollection и дергает методы !!!мне кажется это узким местом программы, потому что если второй пользователь запустит еще одни экземпляр приложения и будет редактировать типы документов, первый пользователь не увидит изменений т.к. загружает все типы документов лишь при создании приложения и хранит их в ОЗУ

Если у вас будет время вникнуть в суть моей писанины и высказать мнение я буду признателен. Отвечу на любой вопрос заинтересовавшихся если что-то не расписал.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38570915
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sadata,
задача как понимаю в учебных целях, ИМХО я бы:
1. использовал какой-нить ORM с поддержкой Linq, partial классы, при необходимости добавлял специфичные методы
2. DataTable - не то что устарел, но уже давно от него и всяких .Fill() с радостью убежали. К таблицам отлично биндятся списки полученные из Linq запросов или просто списки.
3. разделять модель данных и модель формы
4. Настройки лучше хранить в родном App.config либо реестре, раньше усиленно пилили свои XML с настройками лежащий возле EXE, и как попался продвинутый админ сети (у которого пользователи не имеют административных полномочий на компе) - получилась большая папа, у такой программы нет прав читать/писать в ProgramFiles. а App.config пишет в допустимые и предусмотренные для этого места.
5. В виду вышеуказанной сложности, базу FB расположил бы в c:\ProgramData\MyProg, погуглите на тему "где виндовс приложение должно хранить данные и настройки, по феншую"
6. Инсталлер программе делали? )))
7. Как "начинающий" - не бойтесь "оверинженеринга", пробуйте варианты разные, по другому не научиться. На то они и лабы. Сразу сделать "идеально" редко получается, мне кажется даже у гуру программы претерпевают несколько "итераций".
...
Рейтинг: 0 / 0
Архитектура приложения
    #38570919
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sadata,

В принципе, все правильно, только мелочи:
,F_DAY_TO_PERFORM - не надо префикс в имени столбца. И так ясно что это будет.


BindingINI - не нужен, надо использовать app.config. Там все тоже самое, что пишете вы.

любой нестандарт - плохо.

Проблема синхронизации данных в базе - это несколько за уровнем лабораторной работы.
Делать надо только если оно того стоит. А то ведь вы еще забыли про пользователей и привелегии...
:-)

Счас, вам насоветуют....
...
Рейтинг: 0 / 0
Архитектура приложения
    #38570922
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sadataПри запуске приложения и создании главной формы создается объект DocTypeCollection и загружает в себя все данные которые есть, далее по формам ходит только ссылка на объект DocTypeCollection и дергает методы !!!мне кажется это узким местом программы...
Не нужны все данные.
Пользователь "бродит" по списку документов (несколько полей) в гриде.
И только при редактировании грузите в память нужные документ, после его сохраняете в БД.
По таймеру обновляете грид чтоб подтягивать изменения.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38571097
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sadata Тут пример с исходниками простой трёх-звенной информационной системы "от и до" в архитектуре EF -> WCF -> WPF. Может поможет...
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572021
sadata
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
D129,
D129Проблема синхронизации данных в базе - это несколько за уровнем лабораторной работы.
Делать надо только если оно того стоит. А то ведь вы еще забыли про пользователей и привелегии...

Это не совсем лаба, это скорее преддипломная практика. Мне просто на "предприятии" сказали свою хотелку. Да, требований по привилегиям нет, и ходить они будут под dba ролью, но во мне живет маленький перфекционист, и цель больше не удовлетворить заказчика, а удовлетворить себя. Ведь через месяца 2-3 мне искать работу, а при поиске просят показать пример кода. Насколько моя задача подойдет как пример я не знаю, но все таки)
Поэтому синхронизация важна, необходимо реализовать ее правильно. Есть локальная сеть и "сервер" (компьютер в картотеке который не выключают). Сейчас думаю что нибудь в сторону трехзвенки которую предложил Алексей К, посмотрю как реализовано по его ссылке.
Я не уверен в правильности использования таймера как предложил Кифирчик... мы же не можем обновлять каждые 10 секунд, а если делать дольше, то шанс пропустить какую либо транзакцию резко увеличивается и данные будут не актуальны.

ЗЫ инсталлер буду пробовать делать, но пока это не критичный момент)

Спасибо за наводку про app config, устаревший datatable и за ссылку на реальный проект в исходниках)
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572039
sadata
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще дополню, может изначально не правильно расписал

Тип документа будет содержать такую инфу: Название - "Жалоба", До исполнения 7 дней, До предупреждения 4 дня
Потом когда мы создаем сам документ, в главном окне выбираем "Вид документа" (вверху панели). В лист боксе будут наименования документов, у каждого какой либо тип.
Будут генерироваться отчеты на конкретную дату, например какие документы должны быть исполнены срочно
Если документ создан 01.01.2014 и тип документа у него "Жалоба" то необходимо его исполнить до 08.01.2014. Пользователь генерит отчет допустим на 05.01.2014 и ему формируется xls в котором горит эта жалоба и ему необходимо ее срочно исполнить, иначе ему напинают.
Что-то типо того)
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572173
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sadataЭто не совсем лаба, это скорее преддипломная практика.

Трех-звенка это стандартное решение, но несколько "из пушки по воробьям" - для хранения документации...

Можно сделать синхронизацию и в базе данных -
например, при открытии документа на редактирование - помечать его (отдельный столбец - типа кто взял)
И в конце редактирования (при сохранении изменений) - отдавать.
Можно при этом заморочиться транзакцией - но можно и без
Чисто статистически - это будет экстремально редкая ситуация, если одновременно два человека начнут редактировать документ.
Правда, возникнут сопутствующие проблемы, но это всегда так если накручиваешь защиты и предохранители.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572176
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sadataДо исполнения 7 дней, До предупреждения 4 дня


Это трехзвенка. Кто-то должен все время висеть в памяти и отсчитывать эти дни и выписывать люлей.
:-)
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572423
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчик...2. DataTable - не то что устарел, но уже давно от него и всяких .Fill() с радостью убежали. К таблицам отлично биндятся списки полученные из Linq запросов или просто списки.
...Эвон как... А то что DataTable это и есть по сути своей список, ничего? Ну да, теперь тынденция извратиться и использовать всякие нахлобучки в виде LINQ, для студента, без понимания глубинных процессов этого самого LINQ, ну-ну...

Для начала нужно понимать ЧТО и КАК происходит на самом деле. А потом уже использовать те или иные вещи.
В конечном итоге LINQ - лишь синтетический сахар, который выполнит то-же самое что и Fill для DataTable, вот только на Fill можно изнутри прямо в исходнике посмотреть, а для LINQ нужно будет ILDASM-мом по сборке пройтись, чтобы увидеть...

SADATA - в запросах используйте параметры, а не динамическое построение тела запроса, если уж не хотите заморачиваться с хранимыми процедурами...
По поводу макета главного окна - слишком много рамок, "глаза режет". "Отметка об исполнении" - это что? Т.е. жмакнул по переключателю, значит исполнено? Может лучше сделать выпадающий список с определёнными статусами, позволяющими проследить стадии исполнения и т.д.?
Поле краткое содержание лучше сделать пошире, потому как читать текст, который форматирован "столбиком" крайне неудобно, особенно если краткое содержание вовсе не краткое.
Результаты рассмотрения - обычно результаты рассмотрения имеют конечный набор: "Принят", "Отклонён", "В работу" и т.д., Рассмотрите возможность создания списка результатов и его использования. Писать каждый раз одно и то-же не комильфо.

По поводу архитектуры решения: ежели количество пользователей небольшое, и "сервер" вовсе даже и не сервер, а так, клиентская машинка, то замарачиваться в рисованием трёхзвенки особого смысла нет. Проще тригером писать в отдельную таблицу время последних изменений таблиц, которые желательно отслеживать. А в программе отдельным потоком проверять эту таблицу на предмет изменения времени и соответственно в случае необходимости вызывать событие, по которому произойдёт считывание нужных данных. Кстати, в трёхзвенной архитектуре точно также нужно будет продумывать систему уведомлений об изменениях, и опять-же делать это придётся в отдельном потоке.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572481
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex KuznetsovКифирчик...2. DataTable - не то что устарел, но уже давно от него и всяких .Fill() с радостью убежали. К таблицам отлично биндятся списки полученные из Linq запросов или просто списки.
...Эвон как... А то что DataTable это и есть по сути своей список, ничего? Ну да, теперь тынденция извратиться и использовать всякие нахлобучки в виде LINQ, для студента, без понимания глубинных процессов этого самого LINQ, ну-ну...

Для начала нужно понимать ЧТО и КАК происходит на самом деле. А потом уже использовать те или иные вещи.
В конечном итоге LINQ - лишь синтетический сахар, который выполнит то-же самое что и Fill для DataTable, вот только на Fill можно изнутри прямо в исходнике посмотреть, а для LINQ нужно будет ILDASM-мом по сборке пройтись, чтобы увидеть...
1. Ну вот я сперва DataTable во всю использовал, потом наплевавшись (в частности с мержингом кастомной модели в SVN) подумал что будет круто, и старательно пилил свои классы в связке с SqlCommand/SqlDataReader, рефлекшн по полной, тщательно вел поверх этого WCF со своими методами доступа, потом добрался до ORM с поддержкой Linq, и все что раньше кодил неделями, сделал за 3 дня кастомизацией кодогенератора (Т4), при этом количество объектов в самой БД уменьшилось в трое, и при смене модели БД не нужно по несколько файлов исправлять ручками.
А новенькому коллеге, считай после вуза, абсолютно не составило труда юзать ORM+WCF+LINQ не имея дико глубоких познаний в том как это работает. Выводы, рядом подсказать было некому, грабли личные, и недели рабочего времени потрачены в пустую, рутиной.

2. используя linq всегда можно посмотреть какой он sql запрос генерирует, как правило этого более чем достаточно.

3. DataTable/CustomDataSet... ноу комментс. Спросил сейчас коллег, не скучают ли, все улыбнулись (ИМХО). Если вас устраивает эта "обертка", либо в проекте так исторически сложилось - ваше право. В .NET как правило есть несколько путей для решения задачи, каждый выбирает то что считает правильным.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572628
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчики все что раньше кодил неделями, сделал за 3 дня... при этом количество объектов в самой БД уменьшилось в трое...Ахаха, инструмент спроектировал БД быстрее и качественнее, чем разработчик. И последний этим ещё и гордится. Стыдоба!
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572672
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAКифирчики все что раньше кодил неделями, сделал за 3 дня... при этом количество объектов в самой БД уменьшилось в трое...Ахаха, инструмент спроектировал БД быстрее и качественнее, чем разработчик. И последний этим ещё и гордится. Стыдоба!
Какую-то фигню написали. Гексли какой-то.
1. "Инструмент" не проектирует базу, не знаю как там у вас такое получается. "Инструмент" на основе базы данных создал "обертку" классов над таблицами БД. Вы разницу ощущаете?
2. Да, к примеру раньше в БД существовала хранимка реализующая пэйджинг, с появлением линка её необходимость отпала. Объектов в БД стало меньше. Часть логики перекочевала в Linq, несколько изменился подход работы с базой.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572674
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчик...А новенькому коллеге, считай после вуза, абсолютно не составило труда юзать ORM+WCF+LINQ не имея дико глубоких познаний в том как это работает. ... Вы знаете, многим домохозяйкам абсолютно не составляет труда "юзать" автомобили, абсолютно не представляя себе как оно всё там внутри работает, пусть даже и поверхностно. НО, программист не домохозяйка, он обязан понимать, что и как работает в продукте, который он разрабатывает, а уж про используемые технологии и подавно...
"Скажу Вам по секрету", за последние много-много лет ничего принципиально нового в подходе к работе с серверными базами данных не изменилось и не произошло, все также как и прежде: запрос от клиента, выборка данных сервером, получение данных клиентом, "прохождение" по полученному набору данных и их обработка. IMHO изменились лишь обёртки, появились фантики для тех кто хочет "побыстрей" накодить...
Кифирчик... В .NET как правило есть несколько путей для решения задачи, каждый выбирает то что считает правильным.Согласен, кому поп, кому попадья, а кому попова дочка...

Засим считаю сей спор безсмысленным ...
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572716
sphinx_mv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикskyANAпропущено...
Ахаха, инструмент спроектировал БД быстрее и качественнее, чем разработчик. И последний этим ещё и гордится. Стыдоба!
Какую-то фигню написали. Гексли какой-то.
1. "Инструмент" не проектирует базу, не знаю как там у вас такое получается. "Инструмент" на основе базы данных создал "обертку" классов над таблицами БД. Вы разницу ощущаете?Типа, дизайнер датасетов такого не умеет... Аха...
БЕЗ использования "кодогенератора по шаблонам"... И точно не "за три дня" стучания пальцами по клавиатуре, а всего за несколько минут кликания мышкой...
И на ВЫХОДЕ - ОЧЕНЬ СТРОГО типизированные (и даже расширяемые) классы...
Кифирчик2. Да, к примеру раньше в БД существовала хранимка реализующая пэйджинг, с появлением линка её необходимость отпала. Объектов в БД стало меньше. Часть логики перекочевала в Linq, несколько изменился подход работы с базой.Можно подумать, что количество объектов базы данных хоть как-то влияет на сложность поекта... Как минимум, коммутативность от простого переноса функционала из одного места (из базы) в другое (в приложение)...
И шож за проЭкт, в котором удаление одной хранимой процедуры для пэйджинга уменьшает количество "объектов в базе данных в три раза"? 8-0
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572766
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sphinx_mv, чтож все такие фанаты датасетов...
Проект создавался в бородатые времена .NET 2, я еще "под стол пешком ходил". На каждую таблицу была своя ХП Select/Insert/UPdate/Delete, и связанные с ними SqlCommand, и все это с датасетами настроенное и связанное через визуальный редактор.
По мне такая схема явно "не прозрачная", было тяжко все это отлаживать, постоянные проблемы с дизайнером и в виду пересоздания модели.
Тут видимо все сразу стали профи и все умели, и ни про один свой старый проект не могут сказать "я в виду не знания использовал не самый лучший вариант"?
У меня к сожалению такое бывает, и не зная всяких T4, Linq2Sql, EF и прочего стал делать свои классы, методы для них через SqlCommand, DataSet, ручками делал соответствующий WCF сервер, очень познавательно, но довольно трудоемко.

Вот как узнаю что-то новое, по возможности стараюсь исправить свой старый код.

И кодегенератор пилился не для того чтоб сделать тоже самое что делает дизайнер датасетов, это в любом ORM за пару минут делается, а чтоб автоматом генерились всякие enum связанные с таблицами, модели форм и прочие удобства. В пару кликов уложиться не удалось.

По мне сложные ХП в БД лучше реализовать на Linq, как минимум проще отладить C# код чем код в ХП, более читабильно выходит, + пэйджинг, +простейшие выборки - это все переписал на Linq. Чем вас удивляет что в БД и шарпе стало меньше объектов между которыми нужно ловить проблемы?

По мне все стало более "структурировано" и это много проще сопровождать.

какие еще подъе# будут?
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572790
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
КифирчикПо мне сложные ХП в БД
Надеюсь что в данном случае Вы имели ввиду все же бизнес-логику
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572797
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2КифирчикПо мне сложные ХП в БД
Надеюсь что в данном случае Вы имели ввиду все же бизнес-логику
Да, хп в которых много действий и условий, основная бизнес-логика приложения.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572809
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчикsphinx_mv, чтож все такие фанаты датасетов...
Проект создавался в бородатые времена .NET 2, я еще "под стол пешком ходил". На каждую таблицу была своя ХП Select/Insert/UPdate/Delete, и связанные с ними SqlCommand, и все это с датасетами настроенное и связанное через визуальный редактор.
По мне такая схема явно "не прозрачная", было тяжко все это отлаживать, постоянные проблемы с дизайнером и в виду пересоздания модели.
Тут видимо все сразу стали профи и все умели, и ни про один свой старый проект не могут сказать "я в виду не знания использовал не самый лучший вариант"?
У меня к сожалению такое бывает, и не зная всяких T4, Linq2Sql, EF и прочего стал делать свои классы, методы для них через SqlCommand, DataSet, ручками делал соответствующий WCF сервер, очень познавательно, но довольно трудоемко.

Вот как узнаю что-то новое, по возможности стараюсь исправить свой старый код.

И кодегенератор пилился не для того чтоб сделать тоже самое что делает дизайнер датасетов, это в любом ORM за пару минут делается, а чтоб автоматом генерились всякие enum связанные с таблицами, модели форм и прочие удобства. В пару кликов уложиться не удалось.

По мне сложные ХП в БД лучше реализовать на Linq, как минимум проще отладить C# код чем код в ХП, более читабильно выходит, + пэйджинг, +простейшие выборки - это все переписал на Linq. Чем вас удивляет что в БД и шарпе стало меньше объектов между которыми нужно ловить проблемы?

По мне все стало более "структурировано" и это много проще сопровождать.

какие еще подъе# будут?Фишка в том, что всякие T4, Linq2Sql, EF не содержат в себе какой-то чудесный код и не реализуют какие-то магические подходы и не обязательно было ждать их появления, чтобы переписать свой бородатый проект.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572826
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAФишка в том, что всякие T4, Linq2Sql, EF не содержат в себе какой-то чудесный код и не реализуют какие-то магические подходы и не обязательно было ждать их появления, чтобы переписать свой бородатый проект.
Верно! чудес и магии там нет. Но чтоб переписать бородатый проект и не пилить свои велосипеды нужно сперва начать работать там где есть этот бородатый проект и "знать" что есть T4, Linq2Sql, EF, и иметь хотяб небольшой опыт их применения.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38572833
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикskyANAФишка в том, что всякие T4, Linq2Sql, EF не содержат в себе какой-то чудесный код и не реализуют какие-то магические подходы и не обязательно было ждать их появления, чтобы переписать свой бородатый проект.
Верно! чудес и магии там нет.И в чём тогда проблема с тем, чтобы разобраться с тем "ЧТО и КАК происходит на самом деле"?
...
Рейтинг: 0 / 0
Архитектура приложения
    #38573124
sphinx_mv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчикsphinx_mv, чтож все такие фанаты датасетов...Потому что DataSet - самодостаточный и полностью совместим с ЛЮБЫМИ версиями фреймворка.
КифирчикПроект создавался в бородатые времена .NET 2, я еще "под стол пешком ходил". На каждую таблицу была своя ХП Select/Insert/UPdate/Delete, и связанные с ними SqlCommand, и все это с датасетами настроенное и связанное через визуальный редактор.
По мне такая схема явно "не прозрачная", было тяжко все это отлаживать, постоянные проблемы с дизайнером и в виду пересоздания модели.(всплеснул руками) Да, что Вы такого говорите?!
Можно подумать, что пересоздание модели при использовании "других" средств не сущестует в природе - вот просто так и хочется верить... Ага...
И, кстати, в чем (если не секрет) заключаются "проблемы с дизайнером" DataSet'а?
Ну, я "в принципе", знаю о проблемах в дизайнере датасета при использовании одного конкретного сервера баз данных, но тут Вы явно подразумеваете нечто более "глобальное"...
КифирчикТут видимо все сразу стали профи и все умели, и ни про один свой старый проект не могут сказать "я в виду не знания использовал не самый лучший вариант"?
У меня к сожалению такое бывает, и не зная всяких T4, Linq2Sql, EF и прочего стал делать свои классы, методы для них через SqlCommand, DataSet, ручками делал соответствующий WCF сервер, очень познавательно, но довольно трудоемко.Незнание стандартных средств разработки - не повод для гордости... Вообще!..
КифирчикВот как узнаю что-то новое, по возможности стараюсь исправить свой старый код.

И кодегенератор пилился не для того чтоб сделать тоже самое что делает дизайнер датасетов, это в любом ORM за пару минут делается, а чтоб автоматом генерились всякие enum связанные с таблицами, модели форм и прочие удобства. В пару кликов уложиться не удалось.Да, нет там никаких принципиальных "удобств"... Точнее, они есть, но "во дворе"...
КифирчикПо мне сложные ХП в БД лучше реализовать на Linq, как минимум проще отладить C# код чем код в ХП, более читабильно выходит,Улыбнуло... :)
Вы в курсе, что действительно сложная хранимая процедура "немножко больше", чем банальный запрос к данным - максимум, которым Вы можете похвастаться при использовании LINQ...
Кифирчик + пэйджинг, +простейшие выборки - это все переписал на Linq. Чем вас удивляет что в БД и шарпе стало меньше объектов между которыми нужно ловить проблемы?Идеальный, безглючный код - код, котрый не написан.
Ну, а то, что в результате этого перехода Вы огребли добавили кучу зависимого от других нестандартных компонентов кода, который Вам надо связать, написать, отладить и тестировать, а потом отдельно (и дополнительно) сопровождать, совсем не сделало Ваш "проект" менее сложным и более безглючным...
КифирчикПо мне все стало более "структурировано" и это много проще сопровождать.Ну-ну...
Порадовало про "проще сопровождать"... Особенно - когда выйдет новая версия используемого Вами ORM-фреймворка...
...
Рейтинг: 0 / 0
Архитектура приложения
    #38573137
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sphinx_mv,

людям нравится назвать табличку в БД Классом:), чувствуют себя прогерами сразу (ООП орентируетесь? аякж!, вон тъма классов для телефонного справочника)
...
Рейтинг: 0 / 0
Архитектура приложения
    #38573642
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sphinx_mvКифирчикТут видимо все сразу стали профи и все умели, и ни про один свой старый проект не могут сказать "я в виду не знания использовал не самый лучший вариант"? ...Незнание стандартных средств разработки - не повод для гордости... Вообще!..
Протрите очки, где я писал что горжусь этим!? я наоборот писал что не знал, делал глупости и сожалею о потраченном времени.

sphinx_mvПотому что DataSet - самодостаточный и полностью совместим с ЛЮБЫМИ версиями фреймворка.
я высказал свое сугубо личное мнение по поводу датасетов, не пойму что Вы так всбеленились. мне комфортнее не с TypedDataSet . db over wcf в комплекте нравится (хотя предположу что и для TypedDataSet мелкософт что-то подобное придумал), и то что можно не юзать визуального дизайнера и подпилить для себя T4 - тоже нравится, с фреймворками проблем не будет, и в принципе на другой ORM спрыгнуть при необходимости можно.
Кому-то нравятся тойоты, кто-то фанат БМВ.
Вам нравятся типированные датасеты, да пожалуйста, я за Вас рад. Могли бы просто озвучить их плюсы в сравнении с тем же EF, топик стартеру было бы от этого больше пользы.
Собственно и к typed dataset можно linq запросы делать.
У меня был вариант Typed DataSet + дизайнер + куча однотипных хранимок в БД.
вариант с wcf context, Т4 и минимумом ХП мне понравился больше.
Озвучьте свой феншуйный рецепт.

sphinx_mvКифирчик...По мне такая схема явно "не прозрачная", было тяжко все это отлаживать, постоянные проблемы с дизайнером и в виду пересоздания модели.(всплеснул руками) Да, что Вы такого говорите?!
Можно подумать, что пересоздание модели при использовании "других" средств не сущестует в природе - вот просто так и хочется верить... Ага...
И, кстати, в чем (если не секрет) заключаются "проблемы с дизайнером" DataSet'а?
Не сомневаюсь что Вы знаете тип.датасеты лучше меня, и знаете как обойти все сложности, но обсуждать это в форме "всплесков руками" и стеба не интересно.

sphinx_mvКифирчикПо мне сложные ХП в БД лучше реализовать на Linq, как минимум проще отладить C# код чем код в ХП, более читабильно выходит,Улыбнуло... :)
Вы в курсе, что действительно сложная хранимая процедура "немножко больше", чем банальный запрос к данным - максимум, которым Вы можете похвастаться при использовании LINQ...
Даааа..а.. а я то и не знал!!! Х)
"Сложные процедуры" которые я перенес в линк были в Вашей классификации не " действительно сложными " и содержали не "немножко больше чем банальные запросы" а много условий, проверок данных, и вызовов друг друга. ~400 строк в T-SQL ИМХО это жесть, особенно отладка. Допускаю что у Вас будет отличное мнение.
sphinx_mvИдеальный, безглючный код - код, котрый не написан.
Ну, а то, что в результате этого перехода Вы огребли добавили кучу зависимого от других нестандартных компонентов кода, который Вам надо связать, написать, отладить и тестировать, а потом отдельно (и дополнительно) сопровождать, совсем не сделало Ваш "проект" менее сложным и более безглючным...
Не пойму откуда Вы все это берете. Завидую телепатической способности по сообщениям в форуме оценить проект и определить чегож я там отгреб.
...
Рейтинг: 0 / 0
Архитектура приложения
    #38573677
sphinx_mv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчикмне комфортнее не с TypedDataSet . db over wcf в комплекте нравится (хотя предположу что и для TypedDataSet мелкософт что-то подобное придумал), и то что можно не юзать визуального дизайнера и подпилить для себя T4 - тоже нравится, с фреймворками проблем не будет, и в принципе на другой ORM спрыгнуть при необходимости можно .Мечты... Мечты...
А пока "спрыгивать" будете и придется зоопарк из разных фреймворков поддерживать...
В извращениях нужно знать толк.
КифирчикКому-то нравятся тойоты, кто-то фанат БМВ.
Вам нравятся типированные датасеты, да пожалуйста, я за Вас рад. Могли бы просто озвучить их плюсы в сравнении с тем же EF, топик стартеру было бы от этого больше пользы.Самый главный плюс - ЗНАТЬ как это работает на самом деле...
КифирчикСобственно и к typed dataset можно linq запросы делать.И что из этого следует? Сначала выполняем запрос к базе данных, чтобы заполнить датасет, а потом по получившемуся набору эмулируем другой запрос, но уже на LINQ?! Я ничего не упустил?
Теперь это называется "эффективной разработкой"?! Про "эффективные приложения", отмечу, я даже не упоминал...
Банальные сортировки, фильтрация и поиска в данных - и это практически все, что умеет LINQ.
Самой прикольное, что все это можно делать совсем без использования LINQ - и со времен царя гороха.
КифирчикУ меня был вариант Typed DataSet + дизайнер + куча однотипных хранимок в БД.
вариант с wcf context, Т4 и минимумом ХП мне понравился больше.
Озвучьте свой феншуйный рецепт.Фэншуй заключается в том, чтобы знать и уметь пользоваться инструментом - Вы про такой подход в курсе?
Кифирчикsphinx_mv(всплеснул руками) Да, что Вы такого говорите?!
Можно подумать, что пересоздание модели при использовании "других" средств не сущестует в природе - вот просто так и хочется верить... Ага...
И, кстати, в чем (если не секрет) заключаются "проблемы с дизайнером" DataSet'а?Не сомневаюсь что Вы знаете тип.датасеты лучше меня, и знаете как обойти все сложности, но обсуждать это в форме "всплесков руками" и стеба не интересно.Вам задали прямой вопрос о проблемах с дизайнером датасетов, на которые указали именно Вы... Ответ будет?
И Вы что-то намекали про отсутствие необходимости пересоздания модели для не-датасета...
Кифирчикsphinx_mvУлыбнуло... :)
Вы в курсе, что действительно сложная хранимая процедура "немножко больше", чем банальный запрос к данным - максимум, которым Вы можете похвастаться при использовании LINQ...
Даааа..а.. а я то и не знал!!! Х)
"Сложные процедуры" которые я перенес в линк были в Вашей классификации не " действительно сложными " и содержали не "немножко больше чем банальные запросы" а много условий, проверок данных, и вызовов друг друга.Ага... И после переноса на LINQ все это стало работать лучше...
Возможно, мне бы и захотелось в это ПОВЕРИТЬ, но, к сожалению, вот именно в этом вопросе я непробиваемо убежденный атеист. :)
Кифирчик~400 строк в T-SQL ИМХО это жесть, особенно отладка. Допускаю что у Вас будет отличное мнение.Конечно у меня будет отличное мнение: практически любое количество строк не-SQL-кода из T-SQL переводятся в идеальном случае в такое же количество строк на C#. И то, если ОЧЕНЬ повезет... Эффективного способа перевода SQL-запросов в C# нет.
И про "сложности отладки" хранимых процедур рассказывать не надо: слишком уж по-военному эти песни звучат - примерно, как сложности с дизайнером типизированного датасета...
Кифирчикsphinx_mvИдеальный, безглючный код - код, котрый не написан.
Ну, а то, что в результате этого перехода Вы огребли добавили кучу зависимого от других нестандартных компонентов кода, который Вам надо связать, написать, отладить и тестировать, а потом отдельно (и дополнительно) сопровождать, совсем не сделало Ваш "проект" менее сложным и более безглючным...
Не пойму откуда Вы все это берете. Завидую телепатической способности по сообщениям в форуме оценить проект и определить чегож я там отгреб.Не нужно быть телепатом, чтобы уметь оценивать последствия изменений в архитектуре приложения.
...
Рейтинг: 0 / 0
25 сообщений из 66, страница 1 из 3
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Архитектура приложения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]