原文:Xamarin.Android開發實踐(十三)html
經過《Xamarin.Android之SQLiteOpenHelper》和《Xamarin.Android之ContentProvider》的 學習,咱們已經掌握瞭如何使用特定於該平臺的數據庫操做。可是這樣卻和Xamarin所宣稱的跨平臺相違背了,由於這樣咱們就須要針對不一樣的平臺編寫不一樣 的代碼,而本章將使用Github上的開源項目SQLite.NET去解決這個問題,從而能夠實現跨平臺,減小代碼的重複。android
關於該開源項目請點我git
由於這個庫很大,而咱們只須要其中的一個.cs文件就能夠了,因此筆者這裏已經封裝好了一個庫,裏面不只包含了這個庫,還包含了能夠跨平臺的網絡鏈接。github
點我下載sql
由於該庫還使用了一個json庫,因此讀者也一併要下載並引用數據庫
點我下載json
而後新建一個Android Application項目(.net 4.0)而且SDK版本設置爲14(Android 4.0),下面咱們就能夠開始正式學習了。網絡
打開MainActivity類並在頂部加上以下引用app
1 using NSCPAndroid.SQLite;
有過必定開發經驗的人必定會很熟悉ORM,筆者平時用的最多的就是EF、Castle Active Record。固然還有不少其餘更優秀的框架。不熟悉的人也沒有關係,下面咱們只是新建一個類,而這個類的結構徹底是對應到數據庫中的表的。好比筆者在這裏建立一個名爲Stock的表:框架
1 [Table("Stock")] 2 public class StockTable 3 { 4 [PrimaryKey, AutoIncrement, Column("_id")] 5 public int Id { get; set; } 6 7 [MaxLength(8)] 8 public string Symbol { get; set; } 9 }
其中咱們能夠看到Table這個註解屬性,含義就是這個類對應到數據庫中的表名。 讀者不要誤認爲是依照類名,下面就是兩個字段其中關鍵的就是主鍵,由於SQLite規定主鍵必須由自身維護,因此這裏咱們使用了PrimaryKey註解 屬性表示該屬性爲主鍵,AutoIncrement表示該主鍵爲自增,最後就是Column表示該字段對應到該表的字段名(名字必須爲_id),下面一個 就是咱們本身的字段了,筆者使用了MaxLength表示該字段最大能夠保存八個字符。
關於更多的註解屬性能夠看下面的介紹。
[PrimaryKey]:表示該表的主鍵,只能用於Int類型的屬性。
[AutoIncrement]:用於須要自增的屬性,每插入一條新數據該字段都會自增,只能用於Int類型。
[Column(name)]:用來表示指定屬性對應到表中字段的名稱,若是不加該屬性則表中的字段名與屬性名相同。
[Table(name)]:用來表示指定類對應到數據庫中的表名稱,若是不加該屬性則數據庫中的表名稱與該類名稱相同。
[MaxLength(value)]:用來限制字段可以保存的最長字符長度。
[Ignore]:表示忽略該屬性,從而不會在表中生成對應的字段。
[Unique]:表示該屬性的值必須在表中惟一。
咱們須要指定數據庫所保存的路徑,同時還要打開該數據庫。若是不存在該數據庫,則會自動建立該文件。下面的代碼咱們將獲取數據庫的路徑並打開該數據庫:
1 string dbPath = Path.Combine(System.Environment. 2 GetFolderPath(System.Environment.SpecialFolder.Personal),"ormdemo.db3"); 3 var db = new SQLiteConnection(dbPath);
這裏要注意咱們用的是SQLiteConnection打開該數據庫的,而不是SqlConnection。成功打開該數據庫以後剩下的工做咱們只須要利用db就能夠輕鬆完成了,到如今爲止咱們僅僅建立了一個空的數據庫,裏面還不存在任何表。
第2步咱們已經建立好了一個表的結構,下面咱們將在數據庫中建立對應的表,咱們只須要經過下面的代碼就能夠輕鬆的建立一個表了:
1 db.CreateTable<StockTable>();
或者下面這個方式也同樣能夠:
1 db.CreateTable(typeof(StockTable));
建立完以後表仍是空的,因此接下來咱們須要插入幾條數據,這樣才能介紹其餘的操做。
注:實際運用中必定會有人想找如何判斷該表是否已經建立的方法,其實沒有必需要找,即便重複的執行該操做,也不會影響什麼,表一旦建立以後在執行就不會從新建立了。
這裏咱們直接經過建立StockTable的實例來插入到數據庫中,好比下面的代碼咱們將會插入一條數據:
1 var newStock = new StockTable(); 2 newStock.Symbol = "First"; 3 db.Insert(newStock);
是否是十分簡單,僅僅只須要調用Insert便可,該方法還會返回插入數據的主鍵。可是這只是插入一條數據,若是咱們須要插入多條數據呢?固然不可能用foreach,已經提供了另外一個方法InsertAll,好比下面的示例將會同時插入多條數據:
1 List<StockTable> stocks = new List<StockTable> 2 { 3 new StockTable{ 4 Symbol = "First" 5 }, 6 new StockTable{ 7 Symbol = "Second" 8 } 9 }; 10 db.InsertAll(stocks);
若是讀者須要驗證下是否是插入了,咱們能夠獲取該表有多少數據便可,好比下面的代碼:
1 int count = db.Table<StockTable>().Count();
這時表裏已經有數據了,下面咱們就須要進行查詢。
首先介紹最簡單的查詢方式,就是依靠id來直接獲取。固然咱們不須要拼接任何SQL,只須要經過下面這段代碼就能夠獲取id爲1的數據了:
1 var item = db.Get<StockTable>(1);
可是大多數狀況下咱們都須要經過條件語句進行查詢,那樣咱們就須要使用SQL語句了,好比下面的查詢語句,咱們將查詢Symbol開頭爲「F」的數據:
1 var items = db.Query<StockTable>(" select * from Stock where Symbol like ? ", "F%");
相信那些對技術比較追求的人必定知道Linq,它讓咱們擺脫的拼接SQL語句的尷尬,使得查詢變的簡單有趣(複雜的查詢仍是須要採用SQL,甚至是存儲過程等),固然在這裏咱們依然可使用這一特性,下面咱們將上面的代碼改寫成Linq:
1 var items = (from item in db.Table<StockTable>() 2 where item.Symbol.StartsWith("F") 3 select item).GetEnumerator();
筆者爲了可以更快的查看結果,因此使用了GetEnumerator,實際使用中不必定須要。若是讀者喜歡最原始的查詢能夠用ExecuteScalar方法。
注:linq的查詢是屬於延遲查詢的,意味着在查詢的那一刻並無把結果查詢出來,而是等待你使用它的時候才查詢。
推薦:
1.Jesse Liu的隨筆《快樂的lambda表達式》,我的感受頗有意思,也頗有用。
2.關於Linq如何實現動態查詢的文章點我,動態查詢能夠認爲是用字符串拼接Linq的部分語句,這樣作的目的是爲了解決某些特殊場合下的使用。
關於查詢數據到此結束了,下面咱們將學習剩下的兩個操做分別是更新和刪除。
首先咱們先將更新數據,由於它的操做跟插入數據是同樣的存在Update和UpdateAll,只是數據的主鍵須要有數據,不然沒法定位是更新哪一個數據,下面咱們將演示如何利用Update更新數據:
1 var result = (from item in db.Table<StockTable>() 2 where item.Symbol.StartsWith("F") 3 select item).First(); 4 result.Symbol = "Third"; 5 db.Update(result); 6 7 result = db.Get<StockTable>(result.Id);
既然是更新固然須要先獲取一條數據而後更新,最後還要從數據庫中拿出來,肯定是否已經更新成功。下面咱們繼續刪除操做:
1 var result = (from item in db.Table<StockTable>() 2 where item.Symbol.StartsWith("T") 3 select item).First(); 4 5 db.Delete<StockTable>(result.Id);
若是你須要刪除整個表的數據只須要使用DeleteAll便可,固然這些操做都是有限的,因此咱們還須要支持SQL的方法,那麼咱們可使用Execute便可。