Home

Vici CoolStorage Windows Phone support

CoolStorage can be used with Windows Phone 7, without any loss of functionality. It is currently the only ORM available on the Windows Phone platform.

To use CoolStorage in a Windows Phone application, simply add references to Vici.CoolStorage.WP7.dll and Vici.Core.WP7.dll. You can also use NuGet to add the latest version to your project.

Limitations

Local database format

CoolStorage uses SQLite as local data store, which should be stored in isolated storage.

Changes in declaring mapping classes

CoolStorage creates Dynamic Proxies at runtime (using Reflection.Emit). Sadly, this is not supported on Windows Phone. This means that mapping classes can't be declared abstract like this:

// Will not work on Windows Phone
[MapTo("customer")]
public abstract class Customer : CSObject<Customer,int>
{
   public abstract int CustomerID { get; }
   public abstract string Name { get; set; }
   public abstract string City { get; set; }
}

Instead, mapping classes have to be declared as a concrete class, with implementation for getters and setters:

// Windows Phone version of mapping class
[MapTo("customer")]
public class Customer : CSObject<Customer,int>
{
   public int CustomerID { get { return (int)GetField("CustomerID"); } }
   public string Name { get { return (string)GetField("Name"); } set { SetField("Name",value); } }
   public string City { get { return (string)GetField("City"); } set { SetField("City",value); } }
}

The rule is that you should call GetField() and SetField() in the getters and setters, and use the property name as the name parameter (do NOT use the DB column name). The same rule applies to getters and setters for properties mapped to relations. To save you some typing, you can also use _S() instead of SetField(), and _G() instead of SetField().

Connecting to a database

On Windows Phone, the database file has to be stored in Isolated Storage. To make things easier, some convenience methods have been added to the static CSConfig class. The most important method is SetDB(), which takes a file name as parameter. If the file doesn't exist, it will be created and initialized with a blank SQLite database.

// The following line will tell CoolStorage where the database is

CSConfig.SetDB("mydb.sqlite");

// Do your thing
        		

You can also tell CoolStorage to execute a piece of code when the database is first created. This can be used to create the required tables:

// The following line will tell CoolStorage what database file to open,
// create it if it does not exist, and call a delegate which
// creates the necessary tables (only if the database file was
// created new)

CSConfig.SetDB("mydb.sqlite", SqliteOption.CreateIfNotExists, () => {
   CSDatabase.ExecuteNonQuery(@"CREATE TABLE person 
                                 (PersonID INTEGER PRIMARY KEY AUTOINCREMENT,
                                  Name TEXT(50) NOT NULL,
                                  DateOfBirth TEXT(30) NULL)");

});

From here on, you can use all features of CoolStorage. The walkthrough is the best place to start. It briefly explains how CoolStorage works.

Shipping a database with your app

If you have an existing database files (SQLite), you can compile it with your app and use it with CoolStorage. You only have to copy the database from the app's resources to isolated storage.

There are many ways to do this, but here's an example:

// Make sure you set the build action of your database file to "Content" + "Do net copy"

string fn = "mydb.sqlite";

StreamResourceInfo sr = Application.GetResourceStream(new Uri(fn, UriKind.Relative));

IsolatedStorageFile iStorage = IsolatedStorageFile.GetUserStoreForApplication();

if (!iStorage.FileExists(fn))
{
   using (var outputStream = iStorage.OpenFile(fn, FileMode.CreateNew))
   {
      byte[] buffer = new byte[10000];

      for(;;)
      {
         int read = sr.Stream.Read(buffer, 0, buffer.Length);

         if (read <= 0)
             break;

         outputStream.Write(buffer, 0, read);
      }
   }
}

// Now you can use your database

CSConfig.SetDB(fn);

Using multiple databases

CoolStorage supports multiple contexts, where each context is mapped to a different database.

The simplified SetDB() call as described above doesn't allow a context to be specified (yet), but there's an alternative way:

CSConfig.SetDB(new CSDataProviderSqliteWP7("uri=file://" + dbName, contextName));

This way you can map a context name to a specific database file