WPF DataGrid - 无法使用 DataGrid 行上 GUI 中更改的值更新 Sqlite db 文件。它应该通过单击“更新”按钮来保存新值

问题描述 投票:0回答:1

我正在开发一个 WPF 应用程序,该应用程序从 SQLite 数据库读取数据并将其作为 DataGrid 在 XAML 窗口中呈现。

程序可以检索已定义的值并显示为 DataGrid。 DataGrid 名称为“lvdevices”,表示一个列表,其中数据库条目作为对象存储并插入到列表中。我已成功转换数据库条目,因为每一行代表一个对象,然后通过以下代码添加到 lvDevices 列表。“db_devices.db”中的表称为“tbl_devices”。

**MainWindow.xaml.cs **


 public List<Device> devices = new List<Device>();

 public MainWindow(){
       Get_database();
       lvDevices.ItemsSource = devices;

 public class Device
 {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Ip { get; set; }
    public string User { get; set; }
    public string Password { get; set; }
 }      
 public void Get_database()
 {
     string dbFilePath = "C:/Users/USERNAME/source/repos/MyWebBrowser/MyWebBrowser/db_devices.db";
     SqliteConnection connection = new SqliteConnection($"Data Source={dbFilePath}");
     connection.Open();
     string query = "SELECT * FROM tbl_devices";
     SqliteCommand command = new SqliteCommand(query, connection);
     SqliteDataReader reader = command.ExecuteReader();

     while (reader.Read())
     {
         //Make device instance
         Device d = new Device();
         // Access individual columns by their indexes or column names
         int id = reader.GetInt32(0); // assuming the first column is an integer
         string name = reader.GetString(1); // assuming the second column is a string
         string ip = reader.GetString(2);
         string user = reader.GetString(3);
         string password = reader.GetString(4);

         d.Id = id;
         d.Name = name;
         d.Ip = ip;
         d.User = user;
         d.Password = password;

         devices.Add(d);
     }
     reader.Close();
     connection.Close();
 }```

**MainWindow.xaml
**
更新 删除

问题是尝试实现一种使用 SQLU(SQLite) 命令将更改写入数据库的方法。用户在运行的应用程序中手动编辑更改的数据,用户可以在其中看到可编辑的 DataGrid 表。当用户按下同一行上的“更新”按钮时,数据应该更新,该按钮会更新数据库中相应的行列值。 DataGrid 看起来像这样。

DataGrid

我尝试在“更新”按钮单击上实现一个事件。事情是这样的,但经过无数次编辑现在有点混乱。

private void btn_update_Click(object sender, RoutedEventArgs e)
{
    string dbFilePath = "C:/Users/PetterEnoksson/source/repos/MyWebBrowser/MyWebBrowser/db_devices.db";

    SqliteConnection connection = new SqliteConnection($"Data Source={dbFilePath}");
    connection.Open();

    //These two rows belows is just me fooling around with alternative variables
    var editedRow = lvDevices.SelectedCells[0];
    Device dsa = (Device)editedRow.Item;

    TextBlock _id = lvDevices.Columns[0].GetCellContent(lvDevices.Items[0]) as TextBlock;
    TextBlock _name = lvDevices.Columns[1].GetCellContent(lvDevices.Items[0]) as TextBlock;
    TextBlock _ip = lvDevices.Columns[2].GetCellContent(lvDevices.Items[0]) as TextBlock;

    //string dsa_s = dsa.Name.ToString();

    string query = $"INSERT INTO tbl_devices VALUES Name = {_Name.Text}";
    SqliteCommand cmd = new SqliteCommand(query, connection);
    cmd.CommandText = query;

**    //This is where I get an error when clicking the button
**    cmd.ExecuteNonQuery();
    connection.Close();

cmd.ExecuteNonQuery(); 上的错误

Microsoft.Data.Sqlite.SqliteException: 'SQLite Error 1: 'near "Name": syntax error'.'

这是我一直在闲逛的另一种方法,仅供参考。它使用 Sqlite 事务。

public void Write_database(Device new_d)
{
    string dbFilePath = "C:/Users/PetterEnoksson/source/repos/MyWebBrowser/MyWebBrowser/db_devices.db";
    //SqliteConnection connection = new SqliteConnection($"Data Source={dbFilePath}");
    using (SqliteConnection connection = new SqliteConnection($"Data Source={dbFilePath}"))
    {
        connection.Open();
        string query = $"SELECT * FROM tbl_devices WHERE Id={new_d.Id}";
        SqliteCommand command = new SqliteCommand(query, connection);
        SqliteDataReader reader = command.ExecuteReader();
        //reader.Open();

        while (reader.Read())
        {
            using (SqliteTransaction transaction = connection.BeginTransaction())
            {
                string updateQuery = $"UPDATE tbl_devices SET Id = {new_d.Id}, Name = {new_d.Name}, Ip = {new_d.Ip}, User = {new_d.User}, Password = {new_d.Password}";
                using (SqliteCommand _command = new SqliteCommand(updateQuery, connection, transaction))
                {
                    _command.Parameters.AddWithValue("@Id", new_d.Id);
                    _command.Parameters.AddWithValue("@Name", new_d.Id);
                    _command.Parameters.AddWithValue("@Ip", new_d.Ip);
                    _command.Parameters.AddWithValue("@User", new_d.User);
                    _command.Parameters.AddWithValue("@Password", new_d.Password);
                    _command.Transaction.Commit();

                    _command.Transaction.Save("db_devices.db");
                    //reader.Close();
                    _command.ExecuteNonQuery();
                }
            }
        }

    }

我最沮丧的部分是我不知道如何将 DataGrid 上更改的值作为一行检索。我应该使用 SelectedItem / Selected Cells 还是 lv.Devices.Colums 来获取正确的值?如果我想将每一行更改的数据作为设备对象读取,然后使用属性来更新数据库,那么转换部分如何工作。

主要问题是否在于 SQL 格式化,我应该使用 SqliteCommand 来更新更改还是 SqliteTransaction,无论哪种情况,为什么?

DataGrid 的数据绑定是否有错误?

我使用了错误的事件处理程序吗?

非常感谢您的帮助,并对肮脏的代码表示歉意。我已经被困了很长一段时间了,Stack 似乎是我最后的手段。

c# wpf sqlite datagrid
1个回答
0
投票

虽然您创建了命令参数对象,但实际上您似乎并未使用它们,因为在更新语句中您没有引用参数名称(以 @ 开头的参数名称)。
您宁愿直接对值进行字符串插值,这会导致未加引号的字符串出现错误,其中“Name”是第一个。

您只需要使用 SQL 更新语句字符串中的参数,它应该可以工作 - 可能。

string updateQuery = "UPDATE tbl_devices SET Id = @Id, Name = @Name, Ip = @Ip, User = @User, Password = @Password";
// leave the rest as is
© www.soinside.com 2019 - 2024. All rights reserved.