Заполнение БД через приложение WPF

108
12 января 2021, 03:30

Пишу приложение на WPF, которое взаимодействует с БД MySQL. Внутри TabItem есть DataGrid, который выводит данные из БД:

<TabItem x:Name="operations">
            <TabItem.Header>
                <StackPanel>
                    <Label Padding="0,5,0,0" Content="Operations" HorizontalAlignment="Stretch" FontSize="16" MouseLeftButtonDown="operations_click" FontWeight="Bold"></Label>
                </StackPanel>
            </TabItem.Header>
            <TabItem.Content>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <DataGrid AutoGenerateColumns="False" Grid.Row="0" x:Name="operationsGrid" AlternatingRowBackground="#FFC7E3E4" SelectionMode="Single" FontSize="14">
                        <DataGrid.Columns>
                            <DataGridTextColumn Binding="{Binding Date}" Header="Дата" Width="200"/>
                            <DataGridTextColumn Binding="{Binding Cost}" Header="К Оплате" Width="150"/>
                            <DataGridTextColumn Binding="{Binding Currency_name}" Header="Валюта" Width="150"/>
                            <DataGridTextColumn Binding="{Binding cust_surname}" Header="Фамилия Клиента" Width="150"/>
                            <DataGridTextColumn Binding="{Binding cust_firstname}" Header="Имя Клиента" Width="150"/>
                            <DataGridTextColumn Binding="{Binding Service}" Header="Услуга" Width="150"/>
                            <DataGridTextColumn Binding="{Binding Pay_Type}" Header="Тип Оплаты" Width="150"/>
                            <DataGridTextColumn Binding="{Binding emp_Surname}" Header="Фамилия Сотрудника" Width="150"/>
                            <DataGridTextColumn Binding="{Binding emp_firstname}" Header="Имя Сотрудника" Width="150"/>
                        </DataGrid.Columns>
                    </DataGrid>
                    <StackPanel HorizontalAlignment="Center"  Grid.Row="1" Orientation="Horizontal">
                        <Button x:Name="updateOperations" Width="150" Height="50" Margin="0,0,10,10" Content="Обновить" Click="updateOperation" FontSize="14" />
                        <Button x:Name="deleteOperations" Width="150" Height="50" Margin="0,0,10,10" Content="Удалить" Click="deleteOperation" FontSize="14" />
                    </StackPanel>
                </Grid>
            </TabItem.Content>
        </TabItem>

По нажатии на Label внутри TabItem.Header выполняется запрос к БД (последний из методов - обработчик нажатия на кнопку Обновить:

        private void operations_click(object sender, RoutedEventArgs e)
        {
            string sql = "SELECT Date, Cost, Currency_name, customer.Firstname AS cust_firstname, customer.Surname AS cust_surname, nameofservice.Name AS Service, typeofservice.Name AS Pay_Type, employees.Firstname AS emp_firstname, employees.Surname AS emp_Surname FROM operation, currency, customer, sortofservice, nameofservice, employees, typeofservice WHERE operation.Employee = employees.idEmployee AND operation.Sort_of_service = sortofservice.idSort_of_service AND sortofservice.Name = nameofservice.idName_of_service AND sortofservice.Type = typeofservice.idType_of_service AND operation.Customer = customer.idCustomer AND operation.Currency = currency.idCurrency ORDER BY Date";
            operationsTable = new DataTable();
            MySqlConnection connection = null;
            try
            {
                connection = new MySqlConnection(connectionString);
                MySqlCommand command = new MySqlCommand(sql, connection);
                adapter_operations = new MySqlDataAdapter(command);

                adapter_operations.InsertCommand = new MySqlCommand("insert_operation", connection);
                adapter_operations.InsertCommand.CommandType = CommandType.StoredProcedure;
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@dt", MySqlDbType.DateTime, 20, "Date"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@cst", MySqlDbType.VarChar, 45, "Cost"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@curr", MySqlDbType.VarChar, 45, "Currency_name"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@cust_sname", MySqlDbType.VarChar, 45, "cust_surname"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@cust_fname", MySqlDbType.VarChar, 45, "cust_firstname"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@s_name", MySqlDbType.VarChar, 45, "Service"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@s_type", MySqlDbType.VarChar, 45, "Pay_Type"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@empl_sname", MySqlDbType.VarChar, 45, "emp_Surname"));
                adapter_operations.InsertCommand.Parameters.Add(new MySqlParameter("@empl_fname", MySqlDbType.VarChar, 45, "emp_firstname"));
                connection.Open();
                adapter_operations.Fill(operationsTable);
                operationsGrid.ItemsSource = operationsTable.DefaultView;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (connection != null)
                    connection.Close();
            }
        }
        private void UpdateOperation()
        {
            MySqlCommandBuilder comandbuilder = new MySqlCommandBuilder(adapter_operations);
            adapter_operations.Update(operationsTable);
        }
        private void updateOperation(object sender, RoutedEventArgs e)
        {
            UpdateOperation();
        }

SQL Select в более читабельном виде:

SELECT Date, Cost, Currency_name, customer.Firstname AS cust_firstname, customer.Surname AS cust_surname, 
       nameofservice.Name AS Service, typeofservice.Name AS Pay_Type, employees.Firstname AS emp_firstname,
       employees.Surname AS emp_Surname 
FROM   operation, currency, customer, sortofservice, nameofservice, employees, typeofservice 
WHERE  operation.Employee = employees.idEmployee 
       AND operation.Sort_of_service = sortofservice.idSort_of_service 
       AND sortofservice.Name = nameofservice.idName_of_service 
       AND sortofservice.Type = typeofservice.idType_of_service 
       AND operation.Customer = customer.idCustomer 
       AND operation.Currency = currency.idCurrency 
ORDER BY Date

Чтобы внести строку в БД, заполняю ячейки в таблице (данные в последней строке на первом скрине) и по нажатии на кнопку Обновить данные должны появиться в БД, но вылетает exception в месте, указанном на втором скрине.
Вставка информации в БД осуществляется через процедуру (в таблице Operation, куда выполняется вставка, все поля кроме Date, Cost, idOperation являются внешними ключами):

CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_operation`(IN dt datetime, IN cst VARCHAR(45), IN curr VARCHAR(45), IN cust_sname VARCHAR(45), IN cust_fname VARCHAR(45),
                                   IN s_name VARCHAR(45), IN s_type VARCHAR(45), IN empl_sname VARCHAR(45), IN empl_fname VARCHAR(45))
BEGIN
    SET @curr_id = (SELECT idCurrency FROM currency WHERE Currency_name = curr);
    SET @cust_id = (SELECT idCustomer FROM customer WHERE customer.Surname = cust_sname AND customer.Firstname = cust_fname);
    SET @serv_id = (SELECT idSort_of_service FROM sortofservice, typeofservice, nameofservice WHERE sortofservice.Name = nameofservice.idName_of_service AND sortofservice.Type = typeofservice.idType_of_service AND nameofservice.Name = s_name AND typeofservice.Name = s_type);
    SET @empl_id = (SELECT idEmployee FROM employees WHERE employees.Surname = empl_sname AND employees.Firstname = empl_fname);
    SET @op_id = (SELECT count(idOperation) + 1 FROM operation);
    insert into operation (Date, idOperation, Customer, Sort_of_service, Currency, Cost, Employee) VALUES
    (dt, @op_id, @cust_id, @serv_id, @curr_id, cst, @empl_id);
END

Ошибка появляется при выполнении метода Update(operationsTable). Но дело в том, что в operationsTable имеются внесённые данные. В процедуре, похоже, данные в входные параметры не передаются по какой-то причине. Или в чем проблема и как её решить? Благодарю за ответ.

Answer 1

Проблема решена.
В App.config, где определена строка подключения к БД, добавил параметр charset=utf8:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
    <connectionStrings>
        <add name="DefaultConnection"
             connectionString="server=localhost;user=root;database=bank;password=1234;charset=utf8"
             providerName="MySql.Data.MySqlClient"/>
    </connectionStrings>
</configuration>
READ ALSO
WPF Реализация условий, соблюдая паттерн MVVM

WPF Реализация условий, соблюдая паттерн MVVM

Подскажите как реализовать в WPF приложении условияНапример, я хочу, чтобы в зависимости от текста одного TextBlock'a изменялся цвет текста другого...

101
Получение информации о мониторах без WinForms

Получение информации о мониторах без WinForms

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

92
Ошибка при компиляции CS1061

Ошибка при компиляции CS1061

Компилятор пишет сообщение:

114