原文:http://kingsz1.iteye.com/blog/1109156
用 C# 訪問 SQLite 入門 (1)
SQLite 在 VS C# 環境下的開發,網上已經有很多教程。我也是從這些教程開始學習的。而要專門寫下這一篇,是因為按照網上教程的例子,會遇到一些問題,特別是一些細節的設置,沒有具體涉及,往往就讓我這樣的初學者碰壁,明明是全部照搬的卻不斷出錯而不知解決方法。這里就特別記錄和注明我遇到的問題和解決方法,讓其他的初學者可以仿照處理。
這里用到的例子和C#語句,都是從網上來的。
1. 下載安裝 Sqlite ADO.NET
可以從 sourceforge 下載: http://sourceforge.net/projects/sqlite-dotnet2/
安裝則是按提示進行即可
2. 建立Sqlite 數據庫文件
我是在 Firefox 下,安裝 SQLite Manager 來建立的。例如,建立一個 Books.sqlite 數據庫文件:
從 Firefox 菜單 啟動 SQLite Manager, 點 Database -> New Database, 輸入數據庫文件名
然后選擇保存路徑,例如 把文件保存到 桌面。
點 Execute SQL , 在 Enter SQL 區域 輸入建庫語句,如下:
- CREATE TABLE Book
- (
- ID INTEGER,
- BookName VARCHAR(50),
- Price DOUBLE,
- Rowguid VARCHAR(70),
- PRIMARY KEY(ID)
- )
然后點 Run SQL 即可完成建庫工作。
在 SQLite Manager 點 Database -> Close Database, 關閉數據庫並退出 SQLite Manager.
3. 新建 C# Project, 引用 sqlite
新建一個 VC# 的 Windows Form Application, 命名為 dg2 (或其他名)。
在 VS 菜單, 點 Project -> Add Reference
在 .NET 下找到 System.Data.SQLite, 點 OK.
注意了,重點步驟:
在 VS 的右邊,Soultion Explor , References, 點 System.Data.SQLite
然后, 在下面的 Properties 的 Copy Local, 選 True
這一步很重要,如果沒有這個設置,以后在Debug 或 Build 后試運行,會提示找不到 System.Data.SQLite
4. 加入數據庫文件
把數據庫文件放到一個目錄下。先建目錄:
在右邊的 Solution Explorer, 在Project名字上點鼠標右鍵,
在彈出選項,選 Add -> New Folder
然后,給 New Folder 改個名字, 例如 db
把數據庫文件加入到這個 db 目錄之下。
在 db 目錄名上 點鼠標右鍵,在彈出菜單 選 Add -> Existing Item
然后,在打開的文件對話框,找到以前建立的數據庫文件。如上面所示的例子,新建的 Books.sqlite 數據庫文件是放在 桌面,我們就從桌面找到和選中這個文件,點 Add,即可把這個文件加入 db 目錄下。
點一下 這個數據庫文件,在下面的 Properties 選項 Copy to output Directory , 必須選 Copy always
注意: 這個設置很重要。否則就找不到數據庫文件。
5. 建立相關類文件 Class
在 VS 菜單, 點 Project -> Add Class, 給個名字 Book.cs , 點 Add, 然后輸入對 Book類 的定義:
- public class Book
- {
- private int id;
- private string bookName;
- private decimal price;
- private string rowguid;
- public int ID
- {
- get { return id; }
- set { id = value; }
- }
- public string BookName
- {
- get { return bookName; }
- set { bookName = value; }
- }
- public decimal Price
- {
- get { return price; }
- set { price = value; }
- }
- public string Rowguid
- {
- get { return rowguid; }
- set { rowguid = value; }
- }
- public Book()
- { }
- public Book(int _id, string _bookname, decimal _price, string _rowguid)
- {
- id = _id;
- bookName = _bookname;
- price = _price;
- rowguid = _rowguid;
- }
- }
保存。
類似步驟,輸入 數據庫操作類: BookDAL.cs
- public class BookDAL
- {
- public static bool CreateBook(Book book)
- {
- try
- {
- SQLiteConnection conn = new SQLiteConnection("Data Source=db/Books.sqlite;");
- conn.Open();
- SQLiteCommand cmd = conn.CreateCommand();
- cmd.CommandText = "INSERT INTO Book(ID, BookName, Price, Rowguid) VALUES(@ID1, @BookName1, @Price1, @Rowguid1)";
- cmd.Parameters.Add(new SQLiteParameter("ID1", book.ID));
- cmd.Parameters.Add(new SQLiteParameter("BookName1", book.BookName));
- cmd.Parameters.Add(new SQLiteParameter("Price1", book.Price));
- cmd.Parameters.Add(new SQLiteParameter("Rowguid1", book.Rowguid));
- int i = cmd.ExecuteNonQuery();
- return i == 1;
- }
- catch (SQLiteException se)
- {
- MessageBox.Show(se.Message + " \n\n" + se.Source + "\n\n" + se.StackTrace + "\n\n" + se.Data);
- return false;
- }
- catch (ArgumentException ae)
- {
- MessageBox.Show(ae.Message + " \n\n" + ae.Source + "\n\n" + ae.StackTrace + "\n\n" + ae.Data);
- return false;
- }
- catch (Exception ex)
- {
- //Do any logging operation here if necessary
- MessageBox.Show(ex.Message + "\n\n" + ex.Source + "\n\n" + ex.StackTrace + "\n\n" + ex.Data);
- return false;
- }
- }
- public static bool UpdateBookByID(Book book)
- {
- try
- {
- using (SQLiteConnection conn = new SQLiteConnection("Data Source=db/Books.sqlite;"))
- {
- conn.Open();
- SQLiteCommand cmd = conn.CreateCommand();
- cmd.CommandText = "update Book set BookName=@BookName1,Price=@Price1, Rowguid=@Rowguid1 where ID=@ID1;";
- cmd.Parameters.Add(new SQLiteParameter("ID1", book.ID));
- cmd.Parameters.Add(new SQLiteParameter("BookName1", book.BookName));
- cmd.Parameters.Add(new SQLiteParameter("Price1", book.Price));
- cmd.Parameters.Add(new SQLiteParameter("Rowguid1", book.Rowguid));
- int i = cmd.ExecuteNonQuery();
- return i == 1;
- }
- }
- catch (ArgumentException ae)
- {
- MessageBox.Show(ae.Message + " \n\n" + ae.Source + "\n\n" + ae.StackTrace);
- return false;
- }
- catch (Exception ex)
- {
- //Do any logging operation here if necessary
- MessageBox.Show(ex.Message);
- return false;
- }
- }
- public static bool UpdateBookByGuid(Book book)
- {
- try
- {
- using (SQLiteConnection conn = new SQLiteConnection("Data Source=db/Books.sqlite;"))
- {
- conn.Open();
- SQLiteCommand cmd = conn.CreateCommand();
- cmd.CommandText = "update Book set ID=@ID1,BookName=@BookName1,Price=@Price1 where Rowguid=@Rowguid1;";
- cmd.Parameters.Add(new SQLiteParameter("ID1", book.ID));
- cmd.Parameters.Add(new SQLiteParameter("BookName1", book.BookName));
- cmd.Parameters.Add(new SQLiteParameter("Price1", book.Price));
- cmd.Parameters.Add(new SQLiteParameter("Rowguid1", book.Rowguid));
- int i = cmd.ExecuteNonQuery();
- return i == 1;
- }
- }
- catch (ArgumentException ae)
- {
- MessageBox.Show(ae.Message + " \n\n" + ae.Source + "\n\n" + ae.StackTrace);
- return false;
- }
- catch (Exception ex)
- {
- //Do any logging operation here if necessary
- MessageBox.Show(ex.Message);
- return false;
- }
- }
- public static bool DeleteBook(int ID)
- {
- try
- {
- using (SQLiteConnection conn = new SQLiteConnection("Data Source=db/Books.sqlite;"))
- {
- conn.Open();
- SQLiteCommand cmd = conn.CreateCommand();
- cmd.CommandText = "delete from Book where ID=@ID;";
- cmd.Parameters.Add(new SQLiteParameter("ID", ID));
- int i = cmd.ExecuteNonQuery();
- return i == 1;
- }
- }
- catch (ArgumentException ae)
- {
- MessageBox.Show(ae.Message + " \n\n" + ae.Source + "\n\n" + ae.StackTrace);
- return false;
- }
- catch (Exception ex)
- {
- //Do any logging operation here if necessary
- MessageBox.Show(ex.Message);
- return false;
- }
- }
- public static Book GetBookByID(int ID)
- {
- try
- {
- using (SQLiteConnection conn = new SQLiteConnection("Data Source=db/Books.sqlite;"))
- {
- conn.Open();
- SQLiteCommand cmd = conn.CreateCommand();
- cmd.CommandText = "select * from Book where ID=@ID;";
- cmd.Parameters.Add(new SQLiteParameter("ID", ID));
- SQLiteDataReader dr = cmd.ExecuteReader();
- if (dr.Read())
- {
- Book book = new Book();
- book.ID = dr.GetInt32(0);
- book.BookName = dr.GetString(1);
- book.Price = dr.GetDecimal(2);
- return book;
- }
- else
- return null;
- }
- }
- catch (ArgumentException ae)
- {
- MessageBox.Show(ae.Message + " \n\n" + ae.Source + "\n\n" + ae.StackTrace);
- return null;
- }
- catch (Exception ex)
- {
- //Do any logging operation here if necessary
- throw new Exception(ex.Message);
- }
- }
- public static DataTable GetAllBook()
- {
- DataTable dt = new DataTable();
- try
- {
- SQLiteConnection conn = new SQLiteConnection("Data Source=db/Books.sqlite;");
- conn.Open();
- SQLiteCommand cmd = new SQLiteCommand(conn);
- cmd.CommandText = "SELECT * FROM Book";
- cmd.CommandType = CommandType.Text;
- //Console.WriteLine(cmd.CommandText);
- SQLiteDataReader dr = cmd.ExecuteReader();
- if (dr.HasRows)
- {
- dt.Load(dr);
- }
- else {
- //throw new NullReferenceException("No Record Available.");
- }
- dr.Close();
- conn.Close();
- }
- catch (ArgumentException ae)
- {
- MessageBox.Show(ae.Message + " \n\n" + ae.Source + "\n\n" + ae.StackTrace + "\n\n" + ae.Data);
- }
- catch (Exception ex)
- {
- //throw new Exception(ex.Message);
- MessageBox.Show(ex.Message + " \n\n" + ex.Source + "\n\n" + ex.StackTrace + "\n\n" + ex.Data);
- }
- return dt;
- }
- }
在數據庫操作類,因為涉及數據庫的操作,要在 using 部分,必須加入 using System.Data. SQLite 的引用等語句。
- using System.Data;
- using System.Data.SQLite;
- using System.Windows.Forms;
注意了:
初學者都喜歡用別人的代碼來做練習,拷貝過來,粘貼上去,可減少敲鍵盤的時間。但是,在網頁上拷貝代碼,然后貼到 VS里,會引起很多問題。例如 html 的控制符,空格等等,導致以后程序運行出錯,而且不知道錯誤在哪里。明明在屏幕上看到人家的代碼 與 你的代碼是一樣的,但就是出錯。這個時候,就要仔細看看控制符和代碼的問題。
要減少這類問題,在網頁拷貝的代碼, 先粘貼到一個純文本的編輯器,例如 Notepad++ , 然后從 Notepad++ 選擇和復制, 再粘貼到 VS 。
對於粘貼過來的代碼,要特別注意其空格。例如, 下面這個就是從粘貼后的代碼:
可以看到 第14行,18行 等的 空格特別長,當移動光標的時候,它是一個 空格!但實際上它並不是一個空格。一旦運行程序,就會提示記錄記錄為空,實際上是找不到 數據庫文件,或 SQL語句錯誤等等。
處理的辦法很簡單, 就是在這些語句,手工逐個把空格刪掉,然后按一下空格鍵加上空格。就可以發現自己加的空格位是比較小的,呵呵。
這些操作沒有任何技術含量,但也值得分享一下,