Windows Phone Mango,可以将关系数据存储在本地数据库中,本地数据库作为一个文件存储在应用程序的独立存储空间。Windows Phone应用程序使用LINQ to SQL执行数据库的所有操作。LINQ to SQL用于定义数据库架构、选择数据,并将更改保存到数据库文件保存在在独立存储空间。LINQ to SQL是.Net框架的ORM(对象关系映射)平台的数据库。当应用程序执行LINQ语句在运行时,它转换为Transact - SQL对数据库执行操作;一旦数据库返回查询结果,LINQ to SQL将数据转换为应用程序对象。
LINQ to SQL提供了面向对象的方法,用于处理数据,包括对象模型和运行时。LINQ to SQL对象模型是由System.Data.Linq.DataContext对象构成,它充当代理服务器的本地数据库。LINQ to SQL 运行时负责连接本地数据库和应用程序的DataContext对象,如图所示。DataContext对象即数据上下文包含表的对象,其中每个代表在数据库中的表。
图6-4 LINQ to SQL
Windows Phone Mango的应用程序使用的LINQ to SQL访问本地数据库,LINQ to SQL提供一个用于操作存储在数据库中的数据的面向对象的方法。System.Data.Linq.DataContext类连接应用程序的对象模型与数据库中的数据。
在创建本地数据库后,可以使用 LINQ 和数据上下文使用本地数据库。以下部分说明如何选择、 插入、 更新和删除数据库中的数据。
Windows Phone使用语言集成查询 (LINQ) 查询数据库。因为 SQL 查询在 LINQ 中引用的对象映射到数据库中的记录,LINQ to SQL 有别于其他 LINQ 技术正在执行的查询的方式。典型的 LINQ 查询在应用程序层在内存中执行。LINQ to SQL 中,使用的运行库对象关系能力与每个 LINQ 查询以 TRANSACT-SQL 翻译,然后直接在数据库中执行。这样设计在选择大型数据库的少数几个记录的查询时性能会明显增强。
在下面的示例中,一个名为toDoDB的DataContext对象的 LINQ to SQL 查询和结果放到ObservableCollection的ToDoItem对象命名的待办事项。由于延迟执行的数据库查询不实际执行之前的待办事项集合进行实例化。
// Define query to gather all of the to-do items.
var toDoItemsInDB = from ToDoItem todo in toDoDB.ToDoItems
select todo;
// Execute query and place results into a collection.
ToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);
将数据插入数据库是一个两步过程。首先将对象添加到数据上下文中,然后调用SubmitChanges方法来保持数据作为数据库中的行的数据上下文。
在下面的示例中,创建一个ToDoItem对象并添加到的待办事项可观察的集合和相应的数据库表中名为toDoDB的数据上下文。
// Create a new to-do item based on text box.
ToDoItem newToDo = new ToDoItem { ItemName = newToDoTextBox.Text };
// Add the to-do item to the observable collection.
ToDoItems.Add(newToDo);
// Add the to-do item to the local database.
toDoDB.ToDoItems.InsertOnSubmit(newToDo);
注意:
直到调用SubmitChanges方法的数据不会保存到数据库。
更新本地数据库中的数据有三个步骤。第一,要更新的对象数据库中查询。第二,修改所需的对象。最后,调用SubmitChanges方法,以将所做的更改保存到本地数据库。
下面的代码示例显示了应用程序OnNavigatedFrom方法中调用SubmitChanges更新本地数据库中的数据。在SubmitChanges方法调用之前,数据是不会更新至数据库的。
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
//Call base method
base.OnNavigatedFrom(e);
//Save changes to the database
toDoDB.SubmitChanges();
}
删除数据库中的数据也包括三个步骤。首先,查询的数据库中删除的对象。然后,取决于您是否要删除一个或多个对象,调用DeleteOnSubmit或DeleteAllOnSubmit方法,分别放在挂起的删除状态的那些对象。最后,调用SubmitChanges方法,以将所做的更改保存到本地数据库。
在下面的示例中,一个ToDoItem对象是从名为toDoDB的数据库中删除。因为只有一个对象将被删除,在SubmitChanges之前调用DeleteOnSubmit方法。
//Get a handle for the to-do item bound to the button
ToDoItem toDoForDelete = button.DataContext as ToDoItem;
//Remove the to-do item from the observable collection
ToDoItems.Remove(toDoForDelete);
//Remove the to-do item from the local database
toDoDB.ToDoItems.DeleteOnSubmit(toDoForDelete);
//Save changes to the database
toDoDB.SubmitChanges();
注意:
直到调用SubmitChanges方法,是不从数据库删除数据。
Widows Phone应用程序可能需要更改本地数据库架构。Microsoft.Phone.Data.Linq命名空间提供了有关于数据库架构更改的DatabaseSchemaUpdater类。
DatabaseSchemaUpdater类可以执行数据库,例如,添加表、 列、 索引或协会的添加剂更改。对于更复杂的更改,需要创建一个新的数据库,并将数据复制到新的架构。DatabaseSchemaUpdater类提供了可用于以编程方式区分您的数据库的不同版本的DatabaseSchemaVersion属性。
数据库不会反映来自DatabaseSchemaUpdater对象的更新,直到调用Execute方法。当调用该方法时,所有的更改将被提交到本地数据库作为单个事务,包括版本更新。
下面的示例演示如何使用DatabaseSchemaUpdater类修改基于DatabaseSchemaVersion属性的数据库。
using (ToDoDataContext db = new ToDoDataContext(("isostore:/ToDo.sdf")))
{
//Create the database schema updater
DatabaseSchemaUpdater dbUpdate = db.CreateDatabaseSchemaUpdater();
//Get database version
int dbVersion = dbUpdate.DatabaseSchemaVersion;
//Update database as applicable
if (dbVersion < 5)
{ //Copy data from existing database to new database
MigrateDatabaseToLatestVersion();
}
else if (dbVersion == 5)
{ //Add column to existing database to match the data context
dbUpdate.AddColumn<ToDoItem>("TaskURL");
dbUpdate.DatabaseSchemaVersion = 6;
dbUpdate.Execute();
}
}
注意:
在应用程序更新过程中不会改变任何独立存储,包括本地数据库文件中保存的文件。
本地数据库提供密码保护和加密来帮助保护您的数据库。当您使用数据库密码时,加密整个数据库。
下面的示例演示如何创建加密的数据库。
// Create the data context, specify the database file location and password
ToDoDataContext db = new ToDoDataContext ("Data Source='isostore:/ToDo.sdf';Password='securepassword'");
// Create an encrypted database after confirming that it does not exist
if (!db.DatabaseExists()) db.CreateDatabase();
注意:
如果只有有限的非索引列需要进行加密,可通过添加到数据库之前将数据加密,而不是加密整个数据库来实现更好的性能。