Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在使用xamarin ios的生成之间未持久化数据库_Ios_Sqlite_Xamarin.ios_Xamarin - Fatal编程技术网

在使用xamarin ios的生成之间未持久化数据库

在使用xamarin ios的生成之间未持久化数据库,ios,sqlite,xamarin.ios,xamarin,Ios,Sqlite,Xamarin.ios,Xamarin,我正在mac上使用xamarin studio为ios创建一个简单的sqlite驱动的应用程序 sqlite文件是在“personal”文件夹中创建的,并且在构建之间保持不变,但是当我运行应用程序时,我在上一次调试会话中创建的表会消失吗 在我的代码中,在检查文件是否存在后,我使用sqliteconnection进行连接,创建一个表,并从命令对象中插入一行,该行使用ExecuteOnQuery方法。在相同的上下文中,我可以使用第二个命令对象查询表,但是如果我停止调试器并重新启动表,我会去吗 我是否

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

sqlite文件是在“personal”文件夹中创建的,并且在构建之间保持不变,但是当我运行应用程序时,我在上一次调试会话中创建的表会消失吗

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

我是否应该将该文件放在其他文件夹中,它是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);
    }
 }
公共类BaseHandler
{
私有静态bool DbIsUpToDate{get;set;}
const int DB_VERSION=1;//已创建数据库
常量字符串DB_NAME=“mydb.db3”;
受保护的常量字符串CNN\u string=“数据源=“+DB\u NAME+”“版本=3”;
公共BaseHandler()
{
//无需在每次重新启动时多次验证数据库。
如果(DBIsUpdate)
返回;
CheckAndCreateDatabase(数据库名称);
int userVersion=GetUserVersion();
更新的Btoversion(用户版本);
DbIsUpToDate=true;
}
int GetUserVersion()
{
int版本=0;
使用(var cnn=newsqliteconnection(cnn_字符串))
{
cnn.Open();
使用(var cmd=cnn.CreateCommand())
{
cmd.CommandText=“创建表格UV版本(版本整数);”+
“插入到UVERSION(版本)值(1);”;
cmd.ExecuteNonQuery();
}
使用(var cmd=cnn.CreateCommand())
{
cmd.CommandText=“从UVERSION中选择版本;”;
var pragma=cmd.ExecuteScalar();
version=Convert.ToInt32((长)pragma);
}
}
返回版本;
}
void UpdateDBToVersion(int userVersion)
{
//根据当前验证的用户准备sql语句
var sqls=newlist();
如果(用户版本<1)
{
Add(“如果不存在,则创建表MYTABLE(”
+ID整数主键
+“名称文本,”
+“描述文本”
+ ");");
}
//执行update语句
使用(var cnn=newsqliteconnection(cnn_字符串))
{
cnn.Open();
使用(var trans=cnn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
foreach(sqls中的字符串sql)
{
使用(var cmd=cnn.CreateCommand())
{
cmd.CommandText=sql;
cmd.ExecuteNonQuery();
}
}
trans.Commit();
//SetUserVersion(DB_版本);
}
}
}
受保护的字符串GetDBPath(字符串dbName)
{
//获取对文档文件夹的引用
var documents=Environment.GetFolderPath(Environment.SpecialFolder.Personal);
//创建数据库路径
string db=Path.Combine(documents,dbName);
返回分贝;
}
受保护的void CheckAndCreateDatabase(字符串dbName)
{
var dbPath=GetDBPath(dbName);
//确定数据库是否存在
bool dbExists=File.Exists(dbPath);
如果(!dbExists)
SqliteConnection.CreateFile(dbPath);
}
}

同样,我的问题是,每次运行调试器时,它都会运行GetUserVersion,但表UVERSION不会在会话之间持久化。“File.Exists(dbPath)”返回true,因此CreateFile不会运行。为什么数据库是空的?

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

string documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); 
string libraryPath = Path.Combine (documentsPath, "../Library/");
var path = Path.Combine (libraryPath, "MyDatabase.db3");
您可能还想在Github上查看Xamarin的SQLite类:

以下是关于如何使用上述课程的教程:

结果表明,我是使用CNN_字符串创建连接对象的,该字符串只包含db名称,而不是db的完整路径。显然,如果文件不存在,连接对象将创建数据库,因此可能不需要file.Exists(…)。如果没有提供完整的路径,我不确定它是否应该是一个临时数据库,但似乎是这样。将连接对象的创建更改为“datasource=”解决了问题。

听起来您的初始化代码每次都在运行。你能发布一个代码示例吗?也许是一个noob问题,但是使用librarypath的“/”字符,代码是否可以在ios和android之间移植?也许它已经是特定于ios的SpecialFolder.Personal?您可以使用类似这样的条件编译器语句来处理ios和Android之间的差异:不完全符合主题,但如果您在Android中遇到问题,请确保选中Xamarin中的“保留数据”选项: