c# - SQLite问题“无法打开数据库文件”

标签 c# ipad sqlite xamarin.ios

我花了很多时间在Google上搜索并阅读了有关StackOverflow上有关SQLite的其他讨论,但我绝对无法找到对我的问题的任何解释,所以这里是:


上下文 :
我正在为iPad开发一个应用程序,它必须在某些情况下处理一些“大量”数据。在其中之一中,我必须将.kml文件(Google的用于地理数据的xml)中的点坐标导入到我的数据库中,以便以后在MKMapView中重用它们并比在需要显示特定内容时解析xml时加载速度更快。层。
细节 :
导入很容易:在处理这些文件时,我只关心2个表:


其中一个包含区域定义和详细信息:目前,一个integer作为ID,一个text用于命名。
一个包含两个real用于坐标存储,一个integer引用第一个表以了解哪个区域点是其中的一部分。
因此,只要读取我的文件,我就先为新区域创建一个条目,然后将点插入第二个表中,并在第一个表中创建最后一个区域的ID ...没有什么复杂的!


但...
问题 :
在运行了一段时间之后,我从SQLite收到了一条异常消息,并带有著名的消息“无法打开数据库文件”,然后我又无法对数据库进行任何操作。在区域创建或点插入方法中可能会随机发生此异常。
我的反思:
考虑到这些文件中的许多点,我怀疑内存或磁盘已饱和,但我的应用程序的其他部分却丢弃了这些点(在我看来)。
首先,内存:发生异常时,应用程序正在使用大约10或12 MB的RAM。它看起来可能非常大,但这是由于在内存中加载了〜10MB .kml文件,因此可以解释。最重要的是,我的应用程序中的MKMapView可以处理地图上方的大量高分辨率瓷砖图层,因此会导致内存高峰,该高峰可以提供20甚至25MB的内存而不会导致iPad崩溃。
其次,磁盘:重置数据库并仅填充上述2个表时,发生异常时的db文件大小始终约为2.2或2.5MB,但是当我填充其他表时(应用程序的其他部分运行良好!) db文件大约为6或7MB,设备完全没有抱怨。
所以呢?!
CPU焦虑和恐慌?我不这么认为,因为我数据库的其他一些表都以相同的节奏填充而没有问题...并且在模拟器中运行我的应用程序也崩溃了,而核心i7只是在嘲笑这项工作。
SQLite不好用吗?好了!在我看来,这是唯一的解决方案!但是我真的不明白这是怎么回事,因为我以与其他应用程序部分相同的方式处理请求-重复自己-就像一个魅力!
SQLite详细信息:
我有一个DB类,它是一个单例,用于避免我执行的每个请求创建/释放SqliteConnection对象,并且我处理数据库的所有方法都包含在该类中,以确保我不使用在不知道的地方连接。这是有关此类的方法:

public void     saveZone(ObjZone zone)  { //at this point, just creates an entry with a name and let sqlite give it a new id
    lock (connection) { //SqliteConnection object
        try {
            openConnection();
            SqliteCommand cmd = connection.CreateCommand();
            cmd.CommandText = zone.id == 0 ?
                "insert into ZONES (Z_NAME) values (" + format(zone.name) + ") ;" :
                "update ZONES set Z_NAME = " + format(zone.name) + " where Z_ID = " + format(zone.id) + " ;";
            cmd.ExecuteNonQuery();
            if (zone.id == 0) {
                cmd.CommandText = "select Z_ID from ZONES where ROWID = last_insert_rowid() ;";
                zone.id = uint.Parse(cmd.ExecuteScalar().ToString());
            }
            cmd.Dispose();
        }
        catch (Exception e) {
            Log.failure("DB.saveZone(" + zone.ToString() + ") : [" + e.GetType().ToString() + "] - " +
                e.Message + "\n" + e.StackTrace); //custom Console.WriteLine() method with some formating
            throw e;
        }
        finally {
            connection.Close();
        }
    }
}

public void     setPointsForZone(List<CLLocationCoordinate2D> points, uint zone_id) { //registers points for a given zone
    lock (connection) {
        try {
            openConnection();
            SqliteCommand cmd = connection.CreateCommand();
            cmd.CommandText = "delete from ZONESPOINTS where Z_ID = " + format(zone_id);
            cmd.ExecuteNonQuery();
            foreach(CLLocationCoordinate2D point in points) {
                cmd.CommandText = "insert into ZONESPOINTS values " +
                    "(" + format(zi_id) + ", " + format(point.Latitude.ToString().Replace(",", ".")) + ", "
                    + format(point.Longitude.ToString().Replace(",", ".")) + ");";
                cmd.ExecuteNonQuery();
                cmd.Dispose();
            }
        }
        catch (Exception e) {
            Log.failure("DB.setPointsForZone(" + zone_id + ") : [" + e.GetType().ToString() + "] - " + e.Message);  
            throw e;
        }
        finally {
            connection.Close();
        }
    }
}


尽可能清楚地说明,这是上面两个引用的一些方法(我使用此自定义openConnection()方法,因为我在大多数表中使用了外键约束,并且默认情况下未启用级联行为,但是我需要他们。) :

void openConnection() {
    try {
        connection.Open();
        SqliteCommand cmd = connection.CreateCommand();
        cmd.CommandText = "PRAGMA foreign_keys = ON";
        cmd.ExecuteNonQuery();
        cmd.Dispose();
    }
    catch (Exception e) {
        Log.failure("DB.openConnection() : [" + e.GetType().ToString() + "] - " + e.Message);
        throw e;
    }
}

public static string format(object o) {
    return "'" + o.ToString().Replace("'", "''") + "'";
}



好吧,对不起这部小说,我可能已经感谢您阅读所有这些东西了,不是吗?无论如何,如果我错过了可能有用的事情,请告诉我,我会尽快记录下来。
我希望有人能够为我提供帮助,无论如何,先谢谢您!
(我为我可怜的法国人的英语道歉。)

编辑
我的问题是“已解决”!在进行了一些调试目的更改,没有大的修改并且没有成功之后,我将代码放回了已发布的状态...现在可以正常工作了。但是,如果有人可以给我解释可能发生的事情,我将不胜感激!似乎SQLite的行为(至少在iPad上使用-从未在其他地方使用过)有时可能非常晦涩...:/

最佳答案

为此,我不会用力,但是我会尝试两件事:


如果可能,请将KML文件预处理到另一个SQLite数据库,然后使用该数据库将数据导入主数据库中(考虑较低的内存/处理器要求)
小批量处理导入的数据。


高温超导

编辑:您可能已经检查过,但是:unable to open database

关于c# - SQLite问题“无法打开数据库文件”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7327460/

相关文章:

c# - C#中的开源视频手势识别库

c# - regasm/codebase 有效,但使用 regasm/codebase/regfile 生成的文件无效

iphone - 将间接指针转换为 Objective-C 指针

sqlite 格式错误的数据库仅在本地

c# - Controller Action 命名约定

IOS subview 自动调整轮帧值

ios - 有什么方法可以从 iOs 中的 XML/HTML 模板生成 PDF 文件

c# - 为什么我会收到此语法逻辑错误?

c++ - 数据库未连接或更新

c# - 计算物体摩擦力时不准确