使用xamarin ios时,数据库不能在不同版本之间持久化



我在mac上使用xamarin studio为ios创建一个简单的sqlite驱动应用程序。

sqlite文件是在"个人"文件夹中创建的,并在构建之间持久化,但当我运行应用程序时,我在以前的调试会话中创建的表已经消失了?

在我的代码中,在检查文件是否存在之后,我使用sqlitconnection连接并创建一个表,并使用来自命令对象的executenonquery方法插入一行。而在同一上下文中,我可以使用第二个命令对象查询表,但如果我停止调试器并重新启动表,我走了吗?

我应该有文件在不同的文件夹,它是一个设置在xamarin或ios保持表?我无意中使用临时表在sqlite或什么可能是问题?

注意:到目前为止,我只使用入门版本的xamarin和调试iphone模拟器。

public class BaseHandler
{
     private static bool DbIsUpToDate { get; set; }
     const int DB_VERSION = 1;    //Created DB
     const string DB_NAME = "mydb.db3";
     protected const string CNN_STRING = "Data Source=" + DB_NAME + ";Version=3";
     public BaseHandler ()
     {
         //No need to validate database more than once on each restart.
         if (DbIsUpToDate)
             return;
         CheckAndCreateDatabase(DB_NAME);
         int userVersion = GetUserVersion();
         UpdateDBToVersion(userVersion);
         DbIsUpToDate = true;
    }
    int GetUserVersion()
    {
         int version = 0;
         using (var cnn = new SqliteConnection(CNN_STRING)) 
         {
             cnn.Open();
             using (var cmd = cnn.CreateCommand())
             {
                 cmd.CommandText = "CREATE TABLE UVERSION (VERSION INTEGER);" +
                                   "INSERT INTO UVERSION (VERSION) VALUES(1);";
                 cmd.ExecuteNonQuery();
             }
             using (var cmd = cnn.CreateCommand())
             {
                 cmd.CommandText = "SELECT VERSION FROM UVERSION;";
                 var pragma = cmd.ExecuteScalar();
                 version = Convert.ToInt32((long)pragma);
             }
        }
        return version;
    }

    void UpdateDBToVersion(int userVersion)
    {
         //Prepare the sql statements depending on the users current verion
        var sqls = new List<string> ();
         if (userVersion < 1) 
        {
             sqls.Add("CREATE TABLE IF NOT EXISTS MYTABLE ("
                     + " ID INTEGER PRIMARY KEY, "
                     + " NAME TEXT, "
                     + " DESC TEXT "
                     + ");");
        }
         //Execute the update statements
        using (var cnn = new SqliteConnection(CNN_STRING)) 
        {
             cnn.Open();
             using (var trans = cnn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
             {
                foreach(string sql in sqls) 
                {
                    using (var cmd = cnn.CreateCommand())
                    {
                        cmd.CommandText = sql;
                        cmd.ExecuteNonQuery();
                    }
                }
                 trans.Commit();
                 //SetUserVersion(DB_VERSION);
            }
         }
     }
    protected string GetDBPath (string dbName)
    {
         // get a reference to the documents folder
        var documents = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
         // create the db path
        string db = Path.Combine (documents, dbName);
         return db;
    }
    protected void CheckAndCreateDatabase (string dbName)
    {
         var dbPath = GetDBPath(dbName);
         // determine whether or not the database exists
         bool dbExists = File.Exists(dbPath);
         if (!dbExists) 
            SqliteConnection.CreateFile(dbPath);
    }
 }

再一次,我的问题是,每次我运行调试器它运行GetUserVersion,但表UVERSION是不持久的会话之间。"File.Exists(dbPath)"返回true,因此不会运行CreateFile。为什么db是空的?

这是我用来在iOS模拟器中保存数据库的代码片段,数据似乎在应用程序编译之间持续存在:

string documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); 
string libraryPath = Path.Combine (documentsPath, "../Library/");
var path = Path.Combine (libraryPath, "MyDatabase.db3");

你可能还想检查一下SQLite类Xamarin从Github:https://github.com/praeclarum/sqlite-net/tree/master/src

下面是如何使用这个类的教程:http://docs.xamarin.com/recipes/ios/data/sqlite/create_a_database_with_sqlitenet

原来,我正在使用CNN_STRING创建连接对象,它只有db-name而不是db的完整路径。显然,如果文件不存在,则连接对象创建数据库,因此可能不需要file . exists(…)。我不太确定如果没有提供完整的路径,它是否应该是一个临时的数据库,但情况似乎是这样。将连接对象的创建更改为"datasource="就解决了这个问题。

最新更新