2013-05-13 27 views
5

Tôi đang tạo một ứng dụng hướng sqlite đơn giản cho ios sử dụng studio xamarin trên máy mac.Cơ sở dữ liệu không tồn tại giữa các bản dựng với xamarin ios

Tệp sqlite được tạo trong thư mục "cá nhân" và được duy trì giữa các bản dựng nhưng khi tôi chạy ứng dụng, các bảng tôi đã tạo trong phiên gỡ lỗi trước đó đã biến mất?

Trong mã của tôi, sau khi kiểm tra xem tệp có tồn tại không, tôi kết nối bằng cách sử dụng kết nối sqliteconnection và tạo một bảng và chèn một hàng bằng phương thức executeenonquery từ đối tượng lệnh. Trong khi trong cùng một bối cảnh tôi có thể truy vấn bảng bằng cách sử dụng một đối tượng lệnh thứ hai, nhưng nếu tôi dừng trình gỡ lỗi và khởi động lại bảng tôi đi?

Nếu tôi có tệp trong một thư mục khác, đó có phải là cài đặt trong xamarin hoặc ios để giữ bảng không? Tôi vô ý sử dụng bảng tạm thời trong sqlite hoặc những gì có thể là vấn đề?

Lưu ý: cho đến nay tôi chỉ sử dụng phiên bản khởi xamarin và gỡ lỗi trên trình mô phỏng 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); 
    } 
} 

Quay lại đầu trang "File.Exists (dbPath)" trả về true để CreateFile không chạy. Tại sao db trống?

+1

Có vẻ như mã khởi tạo của bạn đang chạy mỗi lần. Bạn có thể gửi mẫu mã không? – Jason

Trả lời

0

Hóa ra rằng tôi đã tạo ra connecti trên đối tượng bằng cách sử dụng CNN_STRING mà chỉ có tên db thay vì đường dẫn đầy đủ đến db. Tốt hơn là đối tượng kết nối tạo cơ sở dữ liệu nếu tệp không tồn tại nên File.Exists (...) có thể không cần thiết. Tôi không thực sự chắc chắn nếu nó phải là một db tạm thời nếu đường dẫn đầy đủ không được cung cấp nhưng nó có vẻ là trường hợp. Thay đổi việc tạo đối tượng kết nối thành "datasource =" đã giải quyết được sự cố.

7

Đây là một đoạn mã tôi đã sử dụng để lưu cơ sở dữ liệu của tôi trong mô phỏng iOS và các dữ liệu dường như vẫn tồn tại giữa ứng dụng biên dịch tốt:

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

Bạn cũng có thể muốn kiểm tra lớp SQLite cho Xamarin tắt của Github: https://github.com/praeclarum/sqlite-net/tree/master/src

Dưới đây là một hướng dẫn về cách sử dụng lớp nói: http://docs.xamarin.com/recipes/ios/data/sqlite/create_a_database_with_sqlitenet

+0

Có lẽ một câu hỏi noob nhưng sử dụng ký tự "/" cho đường dẫn thư viện, mã sẽ có thể di chuyển giữa ios và android không? Có lẽ nó đã là ios cụ thể với SpecialFolder.Personal? – Cliffhanger

+1

Bạn có thể sử dụng các câu lệnh trình biên dịch có điều kiện để xử lý sự khác biệt giữa iOS và Android: http://cl.ly/image/2X1l2b0N002G –

+0

Không chính xác với chủ đề, nhưng nếu bạn gặp sự cố trong Android, hãy đảm bảo kiểm tra tùy chọn 'bảo toàn dữ liệu' trong Xamarin: http://forums.xamarin.com/discussion/4878/database-sqlite-net-do-not-persist-between-build-on-monodroid – rufo

Các vấn đề liên quan