,

Deploying a Database to Isolated Storage

As stated earlier in this chapter, a local database is read-only when it is located in a XAP file. If you want to provide a prepopulated database that is writable from your app, the database must be copied by your app, from your XAP file, to isolated storage.

Like any other resource, such as an image file, an .sdf database file may be stored as content within your app’s XAP file. The app then reads the database file as a Stream of bytes and writes the bytes to isolated storage. After the database has been copied to isolated storage, it is ready to be used by your app.


Note

To prevent the size of your project’s assembly from being unnecessarily increased by the inclusion of a database file, set the file’s Build Action to Content in the Visual Studio Properties pane. This decreases your app’s startup time because it takes less time for the CLR to load a smaller assembly. It does not, however, affect your project’s XAP file size.


Listing 29.6 shows the custom IsolatedStorageUtility class, whose CopyApplicationResourceToIsolatedStorage method locates an application resource and copies it as a stream to a specified location in isolated storage.

LISTING 29.6. IsolatedStorageUtility Class (excerpt)


public class IsolatedStorageUtility : IIsolatedStorageUtility, ISettingsService
{
    public void CopyApplicationResourceToIsolatedStorage(
                        string inResourceName, string outFilename)
    {
        ArgumentValidator.AssertNotNull(inResourceName, "inResourceName");
        ArgumentValidator.AssertNotNullOrWhiteSpace(outFilename, "outFilename");

        Uri uri = new Uri(inResourceName, UriKind.Relative);

        string destination = outFilename;
        int separatorIndex = destination.LastIndexOf("/");
        if (separatorIndex == destination.Length - 1)
        {
            throw new InvalidOperationException(
                string.Format("Destination '{0}' should not end with '/'",
                                destination));
        }

        string directory = null;
        if (separatorIndex != -1)
        {
            directory = destination.Substring(0, separatorIndex);
        }
        using (Stream resourceStream = Application.GetResourceStream(uri).Stream)
        {
            using (IsolatedStorageFile isolatedStorageFile
                        = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!string.IsNullOrWhiteSpace(directory)
                    && !isolatedStorageFile.DirectoryExists(directory))
                {
                    isolatedStorageFile.CreateDirectory(directory);
                }

                using (IsolatedStorageFileStream outStream
                    = isolatedStorageFile.OpenFile(
                                             destination, FileMode.Create))
                {
                    resourceStream.CopyTo(outStream);
                }
            }
        }
    }
...
}


A database file can then be copied from a XAP file to isolated storage in a single step:

IsolatedStorageUtility.CopyApplicationResourceToIsolatedStorage(
        "/Subdirectory/XapDatabase.sdf",
        "/Subdirectory/IsolatedStorageDatabase.sdf");

This can be seen in action in the unit test class named IsolatedStorageUtilityTests, located in the downloadable sample code (see Listing 29.7). The CopyDatabaseToIsolatedStorage test method copies an .sdf file to isolated storage and then verifies that the bytes of both files are equivalent.

The CollectionAssert.AreEquivalent method compares the members of both collections. If all members match, the assert succeeds. The CollectionAssert class is a part of the Windows Phone Toolkit Unit Testing Framework, discussed in Chapter 24, “Unit Testing Apps.”

LISTING 29.7. IsolatedStorageUtilityTests.CopyDatabaseToIsolatedStorage Method


[TestMethod]
public void CopyDatabaseToIsolatedStorage()
{
    const string databaseName = "TestDatabase.sdf";
    IsolatedStorageUtility utility = new IsolatedStorageUtility();
    utility.CopyApplicationResourceToIsolatedStorage(databaseName, databaseName);

    Uri uri = new Uri(databaseName, UriKind.Relative);

    byte[] resourceBytes;

    using (Stream resourceStream = Application.GetResourceStream(uri).Stream)
    {
        resourceBytes = resourceStream.ReadAllBytes();
    }

    Assert.IsNotNull(resourceBytes, "Resource bytes in null");
    Assert.IsTrue(resourceBytes.Length > 0, "Resource bytes length <= 0.");

    using (IsolatedStorageFile isolatedStorageFile
                    = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream outStream
            = isolatedStorageFile.OpenFile(databaseName, FileMode.Open))
        {
            byte[] isolatedStorageBytes = outStream.ReadAllBytes();
            Assert.IsNotNull(isolatedStorageBytes);
            Assert.IsTrue(isolatedStorageBytes.Length > 0);

            CollectionAssert.AreEquivalent(resourceBytes, isolatedStorageBytes);
        }
    }
}


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.167.161