It’s hard to think of an application that doesn’t do something with data. So when your windows mobile application needs a data store more extensible than a text file, you’ll probably turn to SQLCE.
However, don’t think you can use SQLCE the same way you use a desktop or server version. I expect that it is probably true that SQL CE is thread safe and supports multiple connections, as Microsoft claims. You would therefore expect you can use the database the same as any other database you’ve used in the past. However, don’t forget you are running on the window mobile platform, where resources are scarce. As hardware improves and memory increases, you may very well never experience an issue following the same programming paradigm you have always followed. But if you are a user conscientious developer, you will want to consider those poor folks that are still using a windows mobile 5 Smartphone, with low ram and processor power.
If you write your application to open a connection to the database, execute a query, then close and dispose the connection, you may very well run into an intermediate PInvoke error. This error is coming from the interop that is connecting .Net to the native interface for SQLCE. If your experience is as mine was, you will almost always see this error when attempting to open a new connection to the database, after your application has been running for a while, or if you try to open and close several connections in succession. Running multi-threaded access to the database may make the situation worse.
The answer for me was to open a single connection to the database, keep it open for the entire life of the application, and use a mutex to control access to the database, so threads would have to wait their turn to get to the database.
If you are anything like me, opening a connection and not closing and disposing of it, is counter to the nature of being a good developer. Freeing resources at every opportunity, especially if you think the mobile environment is one that really could use those resources back, is the intuitive thing to do. Unfortunately it appears that the very effort of freeing those resources could result in a backlog of garbage collection that actually keeps the resource in play much longer than you expected, potentially creating an issue (PInvoke error). So keeping one connection open suddenly looks better than the alternative.
I implemented a static DataController class through which all data in the SQLCE database is accessed. I then implemented an Initialization method that establishes the database connection and stores it in a private class variable. Finally, I built a TearDown routine, which is called when the application terminates, that closes and disposes of the connection. (You could also implement a singleton pattern and use the constructor and dispose methods to do this, if you want to go to the extra work of building a Singleton). Along with these methods are a couple helper methods to create and destroy the command and resultset objects. Finally, pay close attention to the Lock statement, without which, all the rest would be not much help.
The sample code below creates the core of my data access layer model for Windows Mobile Development. Feel free to leverage what I’ve learned in your own applications.