2013-05-13 28 views
5

我正在使用mac上的xamarin studio创建一个简单的由sqlite驱动的应用程序。数据库不会在使用xamarin构建之间持久保存ios

sqlite文件在“个人”文件夹中创建,并在构建之间保留,但是当我运行应用程序时,我在前一个调试会话中创建的表已不存在?

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

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

注意:到目前为止,我只使用starter版本的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不运行。为什么数据库是空的?

+1

听起来你的初始化代码每次都在运行。你可以发布代码示例吗? – Jason 2013-05-13 23:53:35

回答

0

原来,我创建了connecti使用CNN_STRING,它只有db-name而不是db的完整路径。如果文件不存在,连接对象会创建数据库,因此可能不需要File.Exists(...)。如果没有提供完整的路径,我不确定它应该是临时数据库,但似乎是这样。将连接对象的创建更改为“datasource =”解决了问题。

7

这是一个代码片段,我用来保存我的数据库中的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

+0

也许一个noob问题,但使用库路径的“/”字符,将代码可移植之间的iOS和Android?也许它已经与SpecialFolder.Personal专用? – Cliffhanger 2013-05-15 08:51:22

+1

您可以使用条件编译器语句来处理iOS和Android之间的差异:http://cl.ly/image/2X1l2b0N002G – 2013-05-15 12:28:36

+0

不完全符合主题,但如果您在Android中遇到问题,请务必检查在Xamarin中保存数据选项:http://forums.xamarin.com/discussion/4878/database-sqlite-net-do-not-persist-between-build-on-monodroid – rufo 2013-08-21 22:22:38

相关问题