• [转载]微软WP7本地数据库之Sqlite编程技巧上


    无论是从用户的角度来看还是从开发人员的角度来看,Windows Phone 7给我们带来众多的新的和令人振奋的功能。与此同时,当前的Windows Phone
    7系列也的确存在令许多用户失望的缺憾。一个代表性的遗憾便是,Windows Phone 7缺乏本地数据库API支持—当前的Windows Phone 7操作系统仅提供通过XML、客户端独立存储和云存储等几种有限的数据访问支持。那么,就本地数据库功能来说,我们真的有没有其他的选择了吗?当然不是这样。如今各种开源社团如火如荼,已经有一些开发人员和团队一直努力在填补这一方面的空白。

      请注意,尽管目前已有多个尝试实现了Windows Phone 7本地数据库支持,但最后,这些系统都需要运行于Windows Phone
    7提供的独立存储基础之上。在本系列文章中,我将向你介绍上述成员之一-Sqlite Client for Windows
    Phone。这是一种新的,功能强大且易于使用的Windows Phone
    7本机数据库解决方案,该系统公布于著名的开源网站CodePlex。篇幅所限,我仅介绍在Windows Phone 7系统中使用Sqlite Client for
    Windows Phone编程的部分技巧。


      [备注]本系列文章中的案例程序调试环境包括:


      1. Windows 7;


      2. .NET 4.0;


      3. Visual Studio 2010;


      4. Windows Phone Developer Tools RTW;


      5. Sqlite Client for Windows Phone
    (http://sqlitewindowsphone.codeplex.com/);


      6. (推荐) sqlite-manager (http://code.google.com/p/sqlite-manager/);


      7. (推荐) MVVM Light Toolkit (http://mvvmlight.codeplex.com/).


      一、Sqlite Client for Windows Phone简介


      大家都知道,SQLite是一个著名的开源的嵌入式的数据库系统,目前已经提供对于iOS和Android的良好支持。在此,应当让我们感谢Dan
    Ciprian
    Ardelean,是他带给我们WP7版本的SQLite-C#-SQLite!最近几个月,作者对早期的版本又进行了更新,得到一个功能更强大和更容易使用的解决方案,改名为Sqlite
    Client for Windows
    Phone,在知名的开源网站CodePlex上发布,网址是http://sqlitewindowsphone.codeplex.com/releases。


      1


            ▲图1. 下载Sqlite Client for Windows Phone的界面截图


      Sqlite Client for Windows
    Phone进行大范围的更新,如提供对于布尔类型、大型数据(Blobs)以及事务的全面支持,此外,下载包中还一并提供了一个全面的示例,供开发者学习之用。


      1


           ▲图2. Sqlite Client for Windows Phone源码工程及示例工程架构



      接下来的操作就很简单了:重新构建源码工程,得到一个程序集Community.CsharpSqlite.WP.dll(Release版本大小是525
    KB)。然后,在你的WP7 Silverlight 项目中添加对该程序集的引用。最后,你便可以使用Sqlite Client for Windows
    Phone提供的本地数据库支持功能了。


      二、Sqlite Client for Windows Phone基础类库剖析


      如果您以前有过任何基于SQL脚本的数据库编程经验,那么您可以轻松地使用Sqlite Client for Windows
    Phone功能。特别值得一提的是,此工程建基于以前的C#-SQLite项目之一,通过引入几个帮助器类(在文件SQLiteClient.cs),即SQLiteException、SQLiteConnection和SQLiteCommand,进一步简化了基本的数据库和表相关操作。接下来的几幅图展示了Sqlite
    Client for Windows Phone中提供的主要组件及其之间的关联关系。


      1


              ▲图3. Sqlite Client for Windows Phone最顶层组件


      1


                    ▲图4. SQLiteConnection类中的主要组件


      1


                   ▲图5. SQLiteCommand类中的主要组件


      怎么样!如果您以前熟悉任何基于SQL的数据库开发,相信上面的这些组件对您会非常亲切吧。


      先别急,在正式使用Sqlite Client for Windows
    Phone之前,有必要再向您介绍另外一个非常有用的工具,名为sqlite-manager
    (http://code.google.com/p/sqlite-manager/)。这个工具是以FireFox插件的方式提供的。到现在您应该明白了,绝大多数与SQLite数据库相关的操作,例如创建SQLite数据库、表、视图、索引等等,都可以通过sqlite-manager轻松完成。



      1.使用SQLite Manager简化数据库管理


      如前所述,SQLite Manager是一个Firefox插件,使用Firefox的加载项管理器你可以很容易地获取和安装这个控件(图6)。


      3


              ▲图6. 使用Firefox的加载项管理器获取和安装SQLite Manager插件


      如图所示,如果你打开Firefox的插件管理器,然后输入“SQLite
    Manager”搜索文本,你会很容易检索到此加载项。然后,您可以点击按钮“添加到Firefox... ”开始下载并安装SQLite
    Manager。请注意,在Firefox的提示后,你应该重新启动Firefox以完成安装。


      使用SQLite Manager是容易的。说实在的,这是我第一次使用SQLite
    Manager,我发现这个工具功能强大而且极易上手。如果您使用过VB6中,你可能熟悉其中内置的数据库管理工具-VisData(以便以内置方式创建小型的Access数据库)。说实话,VisData确实是不容易使用,但在当时我们觉得已经相当不错了。现在,你只须记住,SQLite
    Manager的功能要比VisData强大1000倍。下图展示了SQLite Manager的一个使用快照。


      3


                      ▲图7. SQLite Manager使用快照


      从图中可见,你可以使用SQLite
    Manager来实现几种各种SQLite相关操作。请注意,要想了解更多的有关于SQLite的概念及详细使用语法,请从这款插件的帮助菜单中寻找答案。


      另外,你也会注意到,在本文简单的示例工程中,我仅创建了一个表格Customer,对应的数据库文件为database1.sqlite(如图8所示)。


      3


              ▲图8. 使用SQLite Manager定义表格Customer字段


      在创建完数据库database1.sqlite后,关闭SQLite
    Manager插件。然后,把此文件复制或移动到对应示例工程WP7SQLiteClient的根目录下。请注意,接下来,把它的Build
    Action属性设置为Resource模式。设置成这种模式的原因与接下来的操作方式相关。如果选择Content模式,则在后台的示例工程中你需要修改对应的部分源码。



      2.一个有用的工具类-DBHelper


      如上所述,Sqlite Client for Windows
    Phone使用众所周知的SQL操作针对典型的数据库操作提供了一个高层次的封装。因此,在Silverlight for Windows Phone
    7编程中为了处理SQLite数据库操作,我们可以直接使用在文件SQLiteClient.cs中定义的对象(在源库项目),即SQLiteException、SQLiteConnection和SQLiteCommand等。


      虽然Sqlite Client for Windows
    Phone并没有提供与独立存储的直接互动,但显然增加对独立存储支持是必要的,这样可以改善系统的性能。因此,我们可以进一步封装前面提到的SQLiteClient对象。为此,Chris开发了一个非常好用的实用工具类,叫做DBHelper。为了应用于我们自己的示例,我对它做了轻微的修改。完整的源码如下。


      列表1:更新版本的工具类DBHelper





      //others omitted…

      using
    SQLiteClient;

      using System.Linq;

      using
    System.IO.IsolatedStorage;

      using
    System.Collections.Generic;

      using
    System.Collections.ObjectModel;

      namespace
    WP7SQLiteClient.Helpers

      {

      
    public class
    DBHelper

      {

      
    private String
    _dbName;

      
    private SQLiteConnection db = null;

      
    public
    DBHelper(
    String assemblyName, String
    dbName)

      {

      IsolatedStorageFile store
    =IsolatedStorageFile.GetUserStoreForApplication();

      
    if
    (!store.FileExists(dbName))

      {

      CopyFromContentToStorage(assemblyName,
    dbName);

      }

      _dbName
    =
    dbName;

      }

      ~DBHelper()

      {

      Close();

      }

      
    private void
    Open()

      {





      if (db == null)

      {

      db
    = new
    SQLiteConnection(_dbName);

      db.Open();

      }

      }

      
    private void
    Close()

      {

      
    if (db != null)

      {

      db.Dispose();

      db
    =
    null;

      }

      }

      
    //Insert
    operation

      
    public int Insert(T obj, string statement)
    where T :
    new()

      {

      try

      {

      Open();

      SQLiteCommand
    cmd
    =
    db.CreateCommand(statement);

      
    int rec =
    cmd.ExecuteNonQuery(obj);

      return rec;

      }

      catch
    (SQLiteException
    ex)

      {

      System.Diagnostics.Debug.WriteLine(
    "Insert failed:
    "
    +
    ex.Message);

      throw ex;

      }

      }

      
    // Delete
    operation

      
    public void Delete(string statement)
    where T :
    new()

      {

      try

      {






      Open();

      SQLiteCommand cmd
    =
    db.CreateCommand(statement);

      cmd.ExecuteNonQuery();

      }

      catch
    (SQLiteException
    ex)

      {

      System.Diagnostics.Debug.WriteLine(
    "Deletion failed:
    "
    +
    ex.Message);

      throw ex;

      }

      }

      
    //Query
    operation

      
    public List SelectList(String statement)
    where T :
    new()

      {

      Open();

      SQLiteCommand cmd
    =
    db.CreateCommand(statement);

      var lst
    =
    cmd.ExecuteQuery();

      return
    lst.ToList();

      }

      
    public
    ObservableCollection SelectObservableCollection(
    String
    statement)

      where T :
    new()

      {

      List lst
    =
    SelectList(statement);

      ObservableCollection oc
    = new
    ObservableCollection();

      foreach (T item in
    lst)

      {

      oc.Add(item);

      }

      return
    oc;

      }

      
    private void CopyFromContentToStorage(String
    assemblyName,
    String dbName)

      {

      IsolatedStorageFile store
    =

      IsolatedStorageFile.GetUserStoreForApplication();

      System.IO.Stream
    src
    =

      Application.GetResourceStream(

      
    new Uri("/" + assemblyName
    +
    ";component/" +
    dbName,





      UriKind.Relative)).Stream;

      IsolatedStorageFileStream
    dest
    =

      
    new
    IsolatedStorageFileStream(dbName,

      System.IO.FileMode.OpenOrCreate,

      System.IO.FileAccess.Write,
    store);

      src.Position
    = 0;

      CopyStream(src,
    dest);

      dest.Flush();

      dest.Close();

      src.Close();

      dest.Dispose();

      }

      
    private static void
    CopyStream(System.IO.Stream input,

      IsolatedStorageFileStream
    output)

      {

      
    byte[] buffer = new byte[32768];

      
    long TempPos
    =
    input.Position;

      
    int readCount;

      
    do

      {

      readCount
    = input.Read(buffer,
    0,
    buffer.Length);

      
    if (readCount > 0)

      {

      output.Write(buffer,
    0,
    readCount);

      }

      }
    while (readCount
    >
    0);

      input.Position
    =
    TempPos;

      }

      }

      }


      顺便说一句,对于上面这个帮助类我也没有提供细致的优化编码。希望读者根据您的相关工作能够继续进行这项工作(例如提供更好的泛型化的CRUD支持)并分享给广大网友。简言之,我主要是增加了插入和删除方法。上面的代码中最引起您注意是地方一定是方法CopyFromContentToStorage,正是借助这个方法我们实现了上述目标-建立起SQLite数据库与独立存储的关系。


      三、小结


      本文中简要介绍了Sqlite Client for Windows
    Phone的主要功能及相关的辅助开发工具。在接下来的第二篇文章中,我们将具体构建一个简单的Windows Phone 7客户端应用程序,当然要涉及到Sqlite
    Client for Windows Phone的基本编程技巧。

  • 相关阅读:
    hdu 3507 Print Article —— 斜率优化DP
    bzoj 1096 仓库建设 —— 斜率优化DP
    ORDER BY 高级用法之CASE WHEN
    union和union all 的区别
    Ubuntu 链接ln的使用:创建和删除符号链接
    python中set和frozenset方法和区别
    python之sys模块详解
    odoo 8.0 多核启用
    Odoo 中的widget
    Odoo 在 Ubuntu 环境下性能调优
  • 原文地址:https://www.cnblogs.com/fx2008/p/2444052.html
Copyright © 2020-2023  润新知