Не работает сохранение изменений данных для одной из таблиц в .Net C#
Я сохраняю изменения в таблице базы по нажатию на кнопку, вот сам код:
else if (comboBox1.SelectedItem == "Элек")
{
label3.Text = "Электричество";
string script = "SELECT id, name, Mx_pw_VT, Pr_pw_VT, elec_kVT_hr, Print_time_fact, YZV_power_VT FROM elec;";
mycon = new MySqlConnection(connect);
mycon.Open();
MySqlDataAdapter ms_data = new MySqlDataAdapter(script, connect);
var cb = new MySqlCommandBuilder(ms_data);
cb.GetInsertCommand();
ms_data.Update(dataGridView1.DataSource as DataTable);
ms_data.InsertCommand = cb.GetInsertCommand();
ms_data.InsertCommand.CommandText += "; select * from elec where id = last_insert_id();";
ms_data.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
}
Но мне почему то выдает ошибку «Нарушение параллелизма: UpdateCommand затронула 0 из ожидаемых 1 записей.»
Причем у меня есть такой же блок кода для другой таблицы и он работает, в этой таблице изменения происходят, сам блок:
else if (comboBox1.SelectedItem == "Рбт")
{
label3.Text = "Рбт";
string script = "SELECT id, name, Model_preparation_R_Hr, Time_for_preparation_hr, Time_for_post_processing_hr, YZV_work FROM rbt;";
mycon = new MySqlConnection(connect);
mycon.Open();
MySqlDataAdapter ms_data = new MySqlDataAdapter(script, connect);
var cb = new MySqlCommandBuilder(ms_data);
cb.GetInsertCommand();
ms_data.Update(dataGridView1.DataSource as DataTable);
ms_data.InsertCommand = cb.GetInsertCommand();
ms_data.InsertCommand.CommandText += "; select * from rbt where id = last_insert_id();";
ms_data.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
}
Что не так? Подскажите пожалуйста
Ответы (1 шт):
Метод для получения и конвертации ответа от бд (использовать только с SELECT):
public List<T> SqlQuery<T>(string query)
{
var result = new List<T>();
using (MySqlConnection connection = GetDBConnection(1))
{
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = query;
using var reader = command.ExecuteReader();
var columns = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToArray();
var properties = typeof(T).GetProperties();
while (reader.Read())
{
var data = new object[reader.FieldCount];
reader.GetValues(data);
var instance = (T)Activator.CreateInstance(typeof(T));
for (var i = 0; i < data.Length; ++i)
{
if (data[i] == DBNull.Value)
data[i] = null;
var property = properties.SingleOrDefault(x => x.Name.Equals(columns[i], StringComparison.InvariantCultureIgnoreCase));
if (property is not null)
{
var dataValue = Guid.TryParse(data[i].ToString(), out Guid res) is true ? res : data[i];
property.SetValue(instance, Convert.ChangeType(dataValue, property.PropertyType));
}
}
result.Add(instance);
}
}
return result;
}
Метод для получения строки sql-запроса на вставку. Гораздо удобнее. Не нужно писать 1000 и 1 Insert строку для таблиц. Нужно лишь создать класс:
public static string GetInsertSqlString<TValue>(TValue value, string tableName)
{
var columnsName = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(x => x.Name).ToArray();
var values = value.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(x => x.GetValue(value, null));
var hasBool = values.FirstOrDefault(x => x.GetType() == typeof(bool)) is not null;
if (hasBool is false)
return $"INSERT INTO {tableName}({string.Join(",", columnsName)}) VALUES ('{string.Join("','", values)}')";
else
{
List<string> valuesWithBool = new();
foreach (var val in values)
if (val.GetType().Equals(typeof(bool)))
valuesWithBool.Add(val.ToString());
else
valuesWithBool.Add($"'{val}'");
return $"INSERT INTO {tableName}({string.Join(",", columnsName)}) VALUES ({string.Join(",", valuesWithBool)})";
}
}
Метод для Insert:
public DBResponseStatus ExecuteNonQuery(string query)
{
using MySqlConnection myConnection = GetDBConnection();
try
{
if (myConnection.State == ConnectionState.Closed)
myConnection.Open();
MySqlCommand command = new(query, myConnection);
command.ExecuteNonQuery();
return DBResponseStatus.OK;
}
catch (Exception ex)
{
Log.Error(ex.ToString());
return DBResponseStatus.Error;
}
}
Перечисление, которое возвращается из метода ExecuteNonQuery:
public enum DBResponseStatus
{
OK = 0,
Error = 1
}
Метод GetDBConnection для получения строки для БД:
public MySqlConnection GetDBConnection(int timeOut = 30)
{
string connString = "Server=" + Host
+ ";Database=" + DataBaseName
+ ";port=" + Port
+ ";User Id=" + Username
+ ";password=" + Password
+ ";Connection Timeout=" + timeOut;
MySqlConnection conn = new(connString);
return conn;
}
Пример класса для нормальной работы методов:
internal class ProductDB
{
public Guid OrderId { get; set; }
public Guid ProductId { get; set; }
public ProductDB() { }
public ProductDB(Guid orderId, Guid productID)
{
OrderId = orderId;
ProductId = productID;
}
}
Пример вызова метода SqlQuery для Select:
List<Product> GetProducts() =>
DB.SqlQuery<Product>("SELECT * FROM products");
Пример вызова метода ExecuteNonQuery для Insert:
db.ExecuteNonQuery(SQLString.GetInsertSqlString(*экземпляр класса*, "ordersproducts"));