2013-05-04 317 views
2

我目前正在使用Windows Forms和SQLite創建一個小應用程序。閱讀一些教程後,我實現了數據檢索這個方法:使用SQLiteDataAdapter檢索/插入數據

public DataTable GetDataTable(ref SQLiteDataAdapter adapter, string sql) 
     { 
      DataTable dt = new DataTable(); 

      // Connect to database. 
      using (SQLiteConnection connection = new SQLiteConnection(connectionString)) 
      // Create database adapter using specified query 
      using (adapter = new SQLiteDataAdapter(sql, connection)) 
      // Create command builder to generate SQL update, insert and delete commands 
      using (SQLiteCommandBuilder command = new SQLiteCommandBuilder(adapter)) 
      { 
       // Populate datatable to return, using the database adapter     
       adapter.Fill(dt); 
      } 
      return dt; 
     } 

(除了其他GetDataTable不採取SQLiteDataAdapter作爲參數)

我有三個班,我們姑且稱之爲UI,鏈接和數據庫。除了在用戶交互時顯示數據和引發事件之外,UI什麼也不做。該鏈接創建數據庫和SQLiteDataAdapter,通過上述方法檢索數據表,並將其綁定到UI上的數據網格視圖。用戶不能通過數據網格視圖更改表格,但應通過一些文本框來完成。 (這是否使表綁定到dgv obosolete?)

什麼是使用適配器從文本框到數據庫的用戶輸入的最佳方式是什麼?或者我應該使用DataReader和一些插入方法,而不是一個適配器?

據瞭解,UI通過Get方法公開其控件。有更好的解決方案嗎?

private void Initialize() 
{ 
    // Subscribe to userInterface events 
    userInterface.DataGridViewSelectionChanged += new EventHandler(userInterface_DataGridViewSelectionChanged); 
    userInterface.NewClicked += new EventHandler(userInterface_NewClicked); 
    userInterface.SaveClicked += new EventHandler(userInterface_SaveClicked); 

    // Get dataGridView from userInterface and bind to database 
    bindingSource = new BindingSource(); 
    bindingSource.DataSource = database.GetDataTable(ref adapter, "SELECT * FROM SomeTable"); 
    userInterface.GetDataGridView().DataSource = bindingSource; 
} 

void userInterface_DataGridViewSelectionChanged(object sender, EventArgs e) 
{ 
    if (userInterface.GetDataGridView().SelectedRows.Count != 0) 
    { 
     DataGridViewRow row = userInterface.GetDataGridView().SelectedRows[0]; 
     userInterface.GetIDTextBox().Text = row.Cells["PrimaryKey].Value.ToString(); 
     userInterface.GetOtherIDTextBox().Text = row.Cells["ForeignKey"].Value.ToString(); 

     DataTable dt = database.GetDataTable("SELECT * from SomeTable WHERE ForeignKey=" + row.Cells["ForeignKey"].Value); 
     userInterface.GetLastNameTextBox().Text = dt.Rows[0]["LastName"].ToString(); 
     userInterface.GetFirstNameTextBox().Text = dt.Rows[0]["FirstName"].ToString(); 
     userInterface.GetCompanyTextBox().Text = dt.Rows[0]["Company"].ToString(); 
    }    
} 

void userInterface_NewClicked(object sender, EventArgs e) 
{ 
    // Get all text boxes and clear them 
    // Let the UI take care of this by itself?      
} 

void userInterface_SaveClicked(object sender, EventArgs e) 
{ 
     // Get text/data from all text boxes and insert (or update if editing table) into database 
     // adapter.Update(...)? 
} 

乾杯!

回答

3

INSERT,UPDATE和DELETE操作是DbCommand的工作。你需要一個不同的方法,它使用sql字符串和用於INSERT的SQLiteParameter集合。

我會盡量寫一些僞代碼INSERT操作

public class MyHelperClass 
{ 
    public static int InsertCommand(string sql, SQLiteParameter[] parameters) 
    { 
     int result = 0; 
     using (SQLiteConnection connection = new SQLiteConnection(connectionString)) 
     using (SQLiteCommand cmd = new SQLiteCommand(sql, connection)) 
     { 
      cmd.Parameters.AddRange(parameters); 
      result = cmd.ExecuteNonQuery(); 
     } 
     return result; 
    } 
} 

現在你必須建立參數數組傳遞給幫助方法,這應該從你的UI代碼來完成

string sqlCommand = "INSERT INTO table1 (FirstName, LastName) VALUES (@fName, @lName)"; 
SQLiteParameter[] p = new SQLiteParameter[2]; 
p[0] = new SQLiteParameter("@fName", TextBox1.Text); 
p[1] = new SQLiteParameter("@lName", TextBox2.Text); 
int rowAdded = MyHelperClass,InsertCommand(sql, p); 

UPDATE和DELETE命令的操作是相似的。另外,我建議您添加一個GetDataTable版本,該版本接受參數數組而不是使用字符串連接構建sql命令。在這裏重複無數次字符串連接導致錯誤,最糟糕的是,易於暴露給sql注入的弱代碼。

+0

感謝您的快速響應。如果我創建自己的INSERT,UPDATE和DELETE方法,對我來說使用SQLiteDataAdapter更有意義嗎?如果DataGridView只顯示錶格,但通過一些文本框改變它,這是否會使數據從數據庫綁定到DGV過時? – Lahey 2013-05-04 22:54:28

+0

那麼,在這種情況下,dataadapter是無用的,但你可以在將來找到有用的。如果你正在構建一個基礎庫,以便在不同的項目中重用,我將盡力保留這個方法 – Steve 2013-05-04 23:16:54