IT tutorials
 
Technology
 

Windows Phone 8 : Databases and Storage (part 3) - Local Databases - Getting Started

8/15/2013 11:27:41 AM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

3. Local Databases

When you are building an application that needs data that must be queried and support smart updating, a local database is the best way to accomplish that. Windows Phone supports databases that exist directly on the phone. When building a Windows Phone application, you won’t have access to the database directly; instead you can use a variant of LINQ to SQL married to a code-first approach to build a database to accomplish your database access. Let’s walk through the meat of the functionality.

3. Getting Started

To get started, you need a database file. Under the covers the database is SQL Server Compact Edition (SQL CE), so you could just create an .sdf file for your project, but usually you start by telling the database APIs to create the database for you.

The first step is to have a class (or several) that represents the data you want to store. You can start with a simple class:

public class Game
{
  public string Name { get; set; }
  public DateTime? ReleaseDate { get; set; }
  public double? Price { get; set; }
}

This class holds some piece of data you want to be able to store in a database. Before you can store it in the database, you have to add attributes to tell LINQ to SQL that this describes a table:

[Table]
public class Game
{
  [Column]
  public string Name { get; set; }

  [Column]
  public DateTime? ReleaseDate { get; set; }

  [Column]
  public double? Price { get; set; }
}

By using these attributes, you are creating a class that represents the storage for a table in the database. Some of the column information is inferred (such as nullability in the ReleaseDate column). With this definition, you can read from the database, but before you can add or change data, you need to define a primary key:

[Table]
public class Game
{
  [Column(IsPrimaryKey = true, IsDbGenerated = true)]
  public int Id { get; set; }

  [Column]
  public string Name { get; set; }

  [Column]
  public DateTime? ReleaseDate { get; set; }

  [Column]
  public double? Price { get; set; }
}

As you can see, the Column attribute has several properties that can be set to specify information about each column. In this case, the Column attribute specifies that the Id column is the primary key and that the key should be generated by the database. To support change tracking and writing to the database, you must have a primary key.

Like any other database engine, SQL CE enables you to improve query performance by adding your own indexes. You can do this by adding the Index attribute to the table classes:

[Table]
[Index(Name = "NameIndex", Columns = "Name", IsUnique = true)]
public class Game
{
  // ...
}

The Index attribute enables you to specify a name, a string containing the column names to be indexed, and optionally whether the index should also be a unique constraint. This attribute is used when you create or update the database. You can also specify an index on multiple columns by separating the column names with a comma:

[Table]
[Index(Name = "NameIndex", Columns = "Name", IsUnique = true)]
[Index(Columns = "ReleaseDate,IsPublished")]
public class Game : INotifyPropertyChanging, INotifyPropertyChanged
{
  // ...
}

At this point, you have defined a simple table with two indexes and can move on to creating a data context class. This class will be your entry point to the database itself. It is a class that derives from the DataContext class, as shown here:

public class AppContext : DataContext
{
}

This class is responsible for exposing access to the database as well as handling change management. You will expose your “tables” as a public field:

public class AppContext : DataContext
{
  public Table<Game> Games;
}

The generic class wraps your table class to represent a queryable set of those objects. This way, your context class will not only give you access to the objects stored in the database, but also track them for you. The base class (DataContext) is where most of the magic happens. Because the DataContext class does not have an empty constructor, you’ll also need to implement a constructor:

public class AppContext : DataContext
{
  public AppContext()
    : base("DataSource=isostore:/myapp.sdf;")
  {
  }

  public Table<Game> Games;
}

The typical call to the base class’s constructor requires that you send it a connection string. For the phone, all this connection string requires is a description of where the database exists or where it will be created. You specify this by specifying a URI to where the database file belongs. The URI is a path to the file from either the local folder or the application folder. To specify a file to exist (or be created) in the local folder, you use the isostore moniker like so:

isostore:/myapp.sdf

For a database that ships with your application (and will be delivered in the .xap file), you can use the appdata moniker as well. If you want to access data that resides in the application folder, you will be able to only read the database, not write to it. To specify the location of the database in the application folder, you can use the appdata moniker just like the isostore moniker:

appdata:/myapp.sdf

The end of the URI should be a path and a file name to the actual file. The underlying database is SQL CE, so the file is an .sdf file. If you want your database file to be within a subfolder, you can specify it in the URI with the folder name, like so:

isostore:/data/myapp.sdf

After you have created your data context class, you can create the database by calling the CreateDatabase method (as well as checking whether it exists by calling DatabaseExists):

// Create the Context
var ctx = new AppContext();

// Create the Database if it doesn't exist
if (!ctx.DatabaseExists())
{
  ctx.CreateDatabase();
}

The context’s table members allow you to perform CRUD on the underlying data. For example, to create a new Game object in the database, you would just create an instance and add it to the Games member:

// Create a new game object
var game = new Game()
{
  Name = "Gears of War",
  Price = 39.99,
};

// Queue it as a change
ctx.Games.InsertOnSubmit(game);

// Submit all changes (inserts, updates and deletes)
ctx.SubmitChanges();

The new Game object can be passed to the Games member of the context through the InsertOnSubmit method to tell the context to save this the next time changes are submitted to the database. The SubmitChanges method will take any changes that have occurred since the creation of the context object (or since the last call to SubmitChanges) and batch them to the underlying database. Note that the new instance of Game didn’t set the Id property. This is unnecessary because the Id property is marked not only as the primary key (which is required to support writing to the database), but also as database-generated. This means that when SubmitChanges is called, it will let the database generate the Id and update your object’s ID to the database-generated one.

Querying the Games stored in the database takes the form of LINQ queries. So, if you have created some data in the database, you can query it like this:

var qry = from g in ctx.Games
          where g.Price >= 49.99
          order by g.Name
          select g;

var results = qry.ToList();

This query will return a set of Game objects with the data directly from the database. This LINQ query is translated into a parameterized SQL query and executed against the local database for you when this code calls the ToList method.

What might not be obvious is that if you change these objects, the context class tracks those changes for you. So if you change some data, calling the context’s SubmitChanges method updates the database as well:

var qry = from g in ctx.Games
          where g.Name == "Gears of War"
          select g;

var game = qry.First();

game.Price = 34.99;

// Saves any changes to the game
ctx.SubmitChanges();

In addition, you can delete individual items using the table members on the context class by calling DeleteOnSubmit like so:

var qry = from g in ctx.Games
          where g.Name == "Gears of War"
          select g;

var game = qry.FirstOrDefault();

ctx.Games.DeleteOnSubmit(game);

// Saves any chances to the game
ctx.SubmitChanges();

You do need to retrieve the entities to delete them (unlike the full version of LINQ to SQL where you could execute arbitrary SQL). You can submit a deletion by calling DeleteAllOnSubmit and supplying a query:

var qry = from g in ctx.Games
          where g.Price > 100
          select g;

ctx.Games.DeleteAllOnSubmit(qry);

ctx.SubmitChanges();

The query in this example defines the items to be deleted in the database. It does not retrieve them in this place; it uses the query to define which items are to be deleted. After all the items are marked for deletion, the call to SubmitChanges causes the deletion to happen (as well as any other changes detected).

By creating your table classes and a context class, you can access the database and perform all the necessary queries and changes to the database. Next let’s look at additional database features you will probably want to consider as part of your phone application.

 
Others
 
- Windows Phone 8 : Databases and Storage (part 2) - Storage - Serialization
- Windows Phone 8 : Databases and Storage (part 1) - Storage
- Active Directory 2008 : Creating Computers and Joining the Domain (part 3) - Offline Domain Join
- Active Directory 2008 : Creating Computers and Joining the Domain (part 2) - Joining a Computer to the Domain, Secure Computer Creation and Joins
- Active Directory 2008 : Creating Computers and Joining the Domain (part 1) - The Computers Container and OUs
- Exchange Server 2010 : Using the Exchange Management Shell
- Exchange Server 2010 : Using the Exchange Management Shell - Working with Cmdlets
- Exchange Server 2010 : Using the Exchange Management Shell - Using Windows PowerShell
- Administration of Microsoft Lync Server 2010 : Topology Model
- Administration of Microsoft Lync Server 2010 : Role-Based Access Control
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us