在使用xamarin ios的生成之间未持久化数据库
我正在mac上使用xamarin studio为ios创建一个简单的sqlite驱动的应用程序 sqlite文件是在“personal”文件夹中创建的,并且在构建之间保持不变,但是当我运行应用程序时,我在上一次调试会话中创建的表会消失吗 在我的代码中,在检查文件是否存在后,我使用sqliteconnection进行连接,创建一个表,并从命令对象中插入一行,该行使用ExecuteOnQuery方法。在相同的上下文中,我可以使用第二个命令对象查询表,但是如果我停止调试器并重新启动表,我会去吗 我是否应该将该文件放在其他文件夹中,它是xamarin或ios中用于保留表的设置?我是否无意中在sqlite中使用了临时表,或者可能是什么问题 注意:到目前为止,我只使用xamarin的初学者版本,并在iphone模拟器上进行调试在使用xamarin ios的生成之间未持久化数据库,ios,sqlite,xamarin.ios,xamarin,Ios,Sqlite,Xamarin.ios,Xamarin,我正在mac上使用xamarin studio为ios创建一个简单的sqlite驱动的应用程序 sqlite文件是在“personal”文件夹中创建的,并且在构建之间保持不变,但是当我运行应用程序时,我在上一次调试会话中创建的表会消失吗 在我的代码中,在检查文件是否存在后,我使用sqliteconnection进行连接,创建一个表,并从命令对象中插入一行,该行使用ExecuteOnQuery方法。在相同的上下文中,我可以使用第二个命令对象查询表,但是如果我停止调试器并重新启动表,我会去吗 我是否
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中的“保留数据”选项: