Автор: Пользователь скрыл имя, 15 Марта 2011 в 10:38, курсовая работа
Так как цели курсовых работ пересекающиеся, а выбор предметной области свободный, то решено сначала спроектировать систему методами и средствами, изученными на занятиях по предмету «Проектирование информационных систем», а затем создать структуру базы данных и информационную систему, работающую со спроектированной БД, как того требует задание по предмету «Базы данных».
Здесь менеджер по продажам оформляет приход товара от поставщика. Слева в рамке располагаются ссылки на отчеты связанные с остатками товаров на складе.
Полный исходный код главной формы приложения приводить не буду, так как он достаточно велик и содержит немало служебных строк кода. Здесь только самые интересные концепции.
Во-первых, для того чтобы отследить и предотвратить открытие одинаковых форм. Например, нельзя чтобы одновременно было открыто две формы списка или два одинаковых документа. Для этой цели у формы есть специальный параметр, представляющий собой словарь (Dictionary)
public partial class Form1 : Form
{ public IDictionary OpenWindows { get; private set; } public Form1() { InitializeComponent(); this.OpenWindows = new
Dictionary<string, Form>(); } *** |
Для открытия справочника, например, форма проверяет наличие в словаре объекта по названию таблицы. Если такой объект есть, то он становится активным. Если же его нет, то вызывается конструктор формы списка.
private void OpenList(string
TableName)
{ frmListManager list; if (OpenWindows.Contains(TableNam {
list = (frmListManager)OpenWindows[Ta list.Activate(); } else { list = new frmListManager(TableName, this); OpenWindows.Add(TableName, list); list.Show(); } } private void lnkUsers_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { OpenList("users"); } |
Для документов такой функционал располагается в реализации класса для того или иного документа. При закрытии формы справочника или документа, она (форма) удаляет себя из данного объекта.
Второй особенностью главной формы является то, что она должна отображать информацию о документах, содержащихся в БД. Ниже представлен код, для отображения списка заявок текущего пользователя и код для отображения сгруппированных по клиентам заявок.
Здесь применяется несколько из возможностей новой версии языка C#. Такие как вывод типа, анонимные типы и встроенный язык доступа к объектам Linq. Необходимость применения Linq здесь обусловлена необходимостью получения информации о заявках в двух видах: подробном с параметрами каждой заявки и свернутом по номерам заявок. В методе сначала выполняется запрос к БД для получения подробной информации, затем полученная информация конвертируется в анонимный тип, а затем полученная коллекция анонимных типов группируется по составному ключу, включающему идентификатор заявки, дату и статус заявки, а также наименование и количество товара.
public void UpdateOrders()
{ var dt = new DataTable(); string SQLstring = @"SELECT params.id as idrow, params.checked as checked, charac.name as characteristic, params.equality as equality, params.val as val, orderin.id as id, orderin.date as date, kgoods.name as good, orderin.`count` as kol, orderin.status as status FROM orderinparameters as params LEFT JOIN kcharacteristics as charac ON params.characteristic = charac.id LEFT JOIN orderin ON params.idorder = orderin.id LEFT JOIN kgoods ON orderin.good = kgoods.id WHERE orderin.client = '" + MySQL.CurrentUser.Id + "'";
dt.Fill(SQLstring); var parameters = from row in dt.AsEnumerable() select new { check = row.GetBoolCol("checked"), }; // Группировка коллекции по составному ключу, содержащему // код, дату, код товара, количество, статус заявки var orders = from param in parameters group param by new { id = param.idorder, date = param.date, good = param.good, count = param.count, status = param.status } into ord select new // все соберём в отдельный анонимный тип { // для облегчения привязки данных order = ord.Key.id, date = ord.Key.date, good = ord.Key.good, count = ord.Key.count, status = ord.Key.status, OrderParameters = ord }; bsOrderIn.DataSource = orders; } |
Второй метод формы. Необходим для обновления сгруппированной по покупателям информации о необработанных заявках. Код интересен наличием встроенных агрегатных функций и несложного лямбда-выражения. Кроме того SQL запрос здесь на порядок сложнее предыдущего. В нём используется вложенность, группировка и агрегатные функции.
public void UpdateFoldOrders() { var dt = new DataTable(); #region Формирование строки запроса var SQLstring = @"SELECT users.FullName as client, kgoods.name as good, orderin.id as id, orderin.`count` as kol, orderin.status as status, prices.price as price, orderin.`count` * prices.price as summ FROM orderin LEFT JOIN kgoods ON orderin.good = kgoods.id LEFT JOIN users ON orderin.client = users.id LEFT JOIN ( SELECT g.kindOfGood as good, AVG(c.`Value`) as price FROM characteristics as c LEFT JOIN goods as g ON c.good=g.id WHERE kChar = '1' GROUP BY g.kindOfGood ) as prices ON orderin.good=prices.good"; #endregion
dt.Fill(SQLstring); // конвертация DataTable в анонимный тип для облегчения доступа var orders = from row in dt.AsEnumerable() select new { id = row.GetId(), client = row.GetCol("client"), good = row.GetCol("good"),
status = int.Parse(row.GetCol("status") kol = int.Parse(row.GetCol("kol")),
price = float.Parse(row.GetCol("price"
summ = float.Parse(row.GetCol("summ") }; // Группировка по покупателям var clients = from order in orders group order by order.client into gr select new { client = gr.Key, kol = gr.Count(), summ = gr.Sum(p => p.summ), orders = gr }; bsOrderInOnClients.DataSource = clients; } |
Неудачным
решением покажется получение сразу всех
данных, возможных для отображения в таблицах
расшифровки. Однако, так как предполагается
работа приложения через интернет, боле
важным моментом является экономия трафика
и уменьшение задержек при смене строки,
которую необходимо расшифровать.
Форма предназначена
для отображения любых
using System;
using System.Data; using System.Data.Odbc; using System.Windows; using System.Windows.Forms; using System.Linq; namespace winOrders { public partial class frmListManager : Form { private OdbcDataAdapter adapter; private DataTable dt = new DataTable(); private Form1 MainForm; // Имя таблицы БД для отображения списка public string Table { get; private set; } public frmListManager(string tblName, Form1 mForm) {
InitializeComponent(); MainForm = mForm; bindingSource1.DataSource = dt; Table = tblName.Trim(); this.Text = Table.GetSynonym(); // Получение информации о структуре таблицы
DataTable tableStructure = Table.TableStructure(); //"Linq-заклинания" для получения строки SQL запросов и параметров к ней var
SQLparams = tableStructure.AsEnumerable() .Where(row => row.GetName() != "id") // Нужны все, кроме "id" .Select(row => row.GetParameter()); var SqlVars =
tableStructure.AsEnumerable() .Where(row => row.GetName() != "id") // Нужны все, кроме "id" .Select(row => " `" + row.GetName() + "` = ?") // Формирование переменной SQL-запроса .Aggregate((a,
b) => a + ",
" + b); // Сборка в одну
строку adapter = MySQL.GetAdapter("select * from " + Table); adapter.RowUpdated += da_RowUpdated; // Подписка нужна для обновления поля id в dt adapter.InsertCommand = new OdbcCommand("INSERT INTO " + Table + " SET" + SqlVars, MySQL.Connection); foreach (var
row in SQLparams) adapter.InsertCommand.Paramete adapter.UpdateCommand = new OdbcCommand("UPDATE " + Table + " SET" + SqlVars + " WHERE id = ?", MySQL.Connection); foreach (var
row in SQLparams) adapter.UpdateCommand.Paramete
adapter.UpdateCommand.Paramete adapter.DeleteCommand = new OdbcCommand("DELETE FROM " + Table + " WHERE id = ?", MySQL.Connection);
adapter.DeleteCommand.Paramete
adapter.Fill(dt); DataGridViewColumn dgvCol; foreach (DataRow row in tableStructure.Rows) { if (row.GetCol("rTab") == "") { if (row.GetCol("Type") == "tinyint") // у нас это булево { var tmpCol = new DataGridViewCheckBoxColumn(); tmpCol.DataPropertyName = row.GetName(); tmpCol.TrueValue = 1; tmpCol.FalseValue = 0;
tmpCol.AutoSizeMode = DataGridViewAutoSizeColumnMode dgvCol = tmpCol; } else { var tmpCol = new DataGridViewTextBoxColumn();
tmpCol.DataPropertyName = row.GetName(); dgvCol = tmpCol; } } else // Эта колонка - внешняя ссылка { var tmpCol = new DataGridViewComboBoxColumn(); tmpCol.DataPropertyName = row.GetName(); tmpCol.DataSource = new DataTable(row.GetCol("rTab")); tmpCol.ValueMember = row.GetCol("rCol"); tmpCol.DisplayMember = "Name";
tmpCol.DisplayStyle = DataGridViewComboBoxDisplaySty MySQL.GetAdapter("select `" + row.GetCol("rCol") + "`, Name from " +
row.GetCol("rTab")).Fill((Data dgvCol = tmpCol; }
dgvCol.Name = row.GetName(); if (row.GetSynonym() != "") dgvCol.HeaderText = row.GetSynonym(); if (row.GetName() == "id") {// идентификатор редактировать нельзя dgvCol.ReadOnly = true;
dgvCol.AutoSizeMode = DataGridViewAutoSizeColumnMode }
dataGridView1.Columns.Add(dgvC } if (Table == "users") {// Отсюда у пользователей можно поменять только полное наименование, // добавлять/удалять, менять имя/пароль можно только через администратор БД
dataGridView1.AllowUserToAddRo
dataGridView1.AllowUserToDelet
dataGridView1.Columns["Name"]. toolStripButton2.Visible = false; } } void da_RowUpdated(object sender, OdbcRowUpdatedEventArgs e) { if (e.Errors == null && e.StatementType == StatementType.Insert) {// при добавлении новой строки автоинкрементное поле id // само собой в гриде не появляется, надо его так "выковыривать" e.Row["id"] = MySQL.GetLastId().ToString(); } } private void frmListManager_FormClosed(obje {
MainForm.OpenWindows.Remove(Ta } private void frmListManager_Shown(object sender, EventArgs e) { //connection.Open(); } private void dataGridView1_CellEndEdit(obje { if (dt.Rows.Count < dataGridView1.Rows.Count) { // Добавлена строка или ячейка - чекбокс if (dataGridView1[e.ColumnIndex, e.RowIndex] is DataGridViewCheckBoxCell) { // какой-то странный глюк с чекбоксами if (dt.Rows.Count < (dataGridView1.Rows.Count-1)) { // Количество строк другое почему-то при добавлении bindingSource1.EndEdit(); adapter.Update(dt); } else if(dt.Rows[e.RowIndex][e.Colum { bindingSource1.EndEdit(); adapter.Update(dt); } } else { bindingSource1.EndEdit(); adapter.Update(dt); } } else if (dt.Rows[e.RowIndex][e.ColumnI { // Изменено значение bindingSource1.EndEdit(); adapter.Update(dt); } } private void toolStripButton2_Click(object sender, EventArgs e) { DialogResult result = MessageBox.Show("Вы действительно хотите удалить строку?", if (result == DialogResult.OK) {
dataGridView1.Rows.Remove(data adapter.Update(dt); } } } } |
Информация о работе Автоматизированная информационная система «Оптовый продовольственный склад»