与众不同 windows phone (7) - Local Database(本地数据库)
2014-02-22 19:08
267 查看
原文:与众不同 windows phone (7) - Local Database(本地数据库)[索引页]
[源码下载]
[align=center]与众不同 windows phone (7) - Local Database(本地数据库)[/align]
作者:webabcd
介绍
与众不同 windows phone 7.5 (sdk 7.1) 之本地数据库
概述
演示如何使用“本地数据库”
示例
1、概述
Summary.xaml
2、使用“本地数据库”的 Demo
Model层 - ModelBase.cs
Model层 - Category.cs
public class Category : ModelBase
{
// 版本列,可以显著改进表的更新性能
[Column(IsVersion = true)]
private Binary _version;
private int _categoryId;
/*
* Column - 将属性标记为数据表中的一个字段
* IsPrimaryKey - 是否是主键
* IsDbGenerated - 数据是否由数据库自动生成,如自增列
* DbType = "INT NOT NULL Identity" - int类型,不能为null,标识列
* CanBeNull - 是否可以为 null
* AutoSync = AutoSync.OnInsert - 标记此值的作用是:当数据添加完成后,此属性的值会自动同步为数据库自增后的值
*/
[Column(DbType = "INT NOT NULL IDENTITY", IsDbGenerated = true, IsPrimaryKey = true)]
public int CategoryId
{
get { return _categoryId; }
set
{
NotifyPropertyChanging("CategoryId");
_categoryId = value;
NotifyPropertyChanged("CategoryId");
}
}
private string _name;
[Column]
public string Name
{
get { return _name; }
set
{
NotifyPropertyChanging("Name");
_name = value;
NotifyPropertyChanged("Name");
}
}
private EntitySet<Product> _products;
/*
* Association - 用于标记表之间的关联关系
* Storage - 指定用于保存关联数据的私有字段。本例中类型为 EntitySet<T> 的私有字段 _products 用于保存关联数据,本例中所谓的关联数据就是 Category 下的 Products
* ThisKey - 关联数据在本表中所对应的 key 字段
* OtherKey - 关联数据在他表中所对应的 key 字段
* IsForeignKey - 是否是外键
*/
[Association(Storage = "_products", ThisKey = "CategoryId", OtherKey = "_categoryId")]
public EntitySet<Product> Products
{
get { return this._products; }
set
{
/*
* Assign() - 将一个 EntitySet<T> 赋值给另一个 EntitySet<T>
*/
// 将 value 赋值给 _products
this._products.Assign(value);
}
}
// 指定 _products 做添加和删除操作时的关联操作
public Category()
{
_products = new EntitySet<Product>
(
new Action<Product>(this.attach),
new Action<Product>(this.detach)
);
}
// _products 添加 Product 时的关联操作
private void attach(Product product)
{
NotifyPropertyChanging("Product");
product.Category = this;
}
// _products 删除 Product 时的关联操作
private void detach(Product product)
{
NotifyPropertyChanging("Product");
product.Category = null;
}
}
}[Index(Columns = "Name ASC, ProductId DESC", Name="MyIndex")]
public class Product : ModelBase
{
// 版本列,可以显著改进表的更新性能
[Column(IsVersion = true)]
private Binary _version;
private int _productId;
/*
* Column - 将属性标记为数据表中的一个字段
* IsPrimaryKey - 是否是主键
* IsDbGenerated - 数据是否由数据库自动生成,如自增列
* DbType = "INT NOT NULL Identity" - int类型,不能为null,标识列
* CanBeNull - 是否可以为 null
* AutoSync = AutoSync.OnInsert - 标记此值的作用是:当数据添加完成后,此属性的值会自动同步为数据库自增后的值
*/
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int ProductId
{
get { return _productId; }
set
{
if (_productId != value)
{
NotifyPropertyChanging("ProductId");
_productId = value;
NotifyPropertyChanged("ProductId");
}
}
}
private string _name;
[Column]
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
NotifyPropertyChanging("Name");
_name = value;
NotifyPropertyChanged("Name");
}
}
}
private double _price;
[Column]
public double Price
{
get { return _price; }
set
{
if (_price != value)
{
NotifyPropertyChanging("Price");
_price = value;
NotifyPropertyChanged("Price");
}
}
}
[Column]
internal int _categoryId;
private EntityRef<Category> _category;
/*
* Association - 用于标记表之间的关联关系
* Storage - 指定用于保存关联数据的私有字段。本例中类型为 EntityRef<T> 的私有字段 _category 用于保存关联数据,本例中所谓的关联数据就是 Product 所属的 Category
* ThisKey - 关联数据在本表中所对应的 key 字段
* OtherKey - 关联数据在他表中所对应的 key 字段
* IsForeignKey - 是否是外键
*/
[Association(Storage = "_category", ThisKey = "_categoryId", OtherKey = "CategoryId", IsForeignKey = true)]
public Category Category
{
get { return _category.Entity; }
set
{
NotifyPropertyChanging("Category");
// 更新 Storage 以及 ThisKey
_category.Entity = value;
if (value != null)
_categoryId = value.CategoryId;
NotifyPropertyChanging("Category");
}
}
}
}
[源码下载]
[align=center]与众不同 windows phone (7) - Local Database(本地数据库)[/align]
作者:webabcd
介绍
与众不同 windows phone 7.5 (sdk 7.1) 之本地数据库
概述
演示如何使用“本地数据库”
示例
1、概述
Summary.xaml
<phone:PhoneApplicationPage x:Class="Demo.LocalDatabase.Summary" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <TextBlock TextWrapping="Wrap"> <Run>本地数据库概述</Run> <LineBreak /> <LineBreak /> <Run>1、App 创建数据库时,其文件会被保存到独立存储;程序包内数据库只能被读取,如果需要更新它,则必须把其复制到独立存储后再操作</Run> <LineBreak /> <Run>2、数据库结构发生改变时优先使用 DatabaseSchemaUpdater 来更新数据库结构;数据迁移是下策</Run> <LineBreak /> <Run>3、只读场景下建议将 DataContext 的 ObjectTrackingEnabled 设置为 false(因为只读时不需要对象跟踪),从而关闭对象跟踪以减小内存使用量</Run> <LineBreak /> <Run>4、在多线程操作本地数据库的场景下,建议使用互斥锁,即 System.Threading.Mutex</Run> </TextBlock> </Grid> </phone:PhoneApplicationPage>
2、使用“本地数据库”的 Demo
Model层 - ModelBase.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.ComponentModel; using System.Data.Linq.Mapping; using System.Data.Linq; namespace Demo.LocalDatabase.Model { public class ModelBase : INotifyPropertyChanged, INotifyPropertyChanging { // 实现 INotifyPropertyChanged 是为了属性变更后的通知 public event PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } // 实现 INotifyPropertyChanging 是为了最大限度地减少内存使用量(NotifyPropertyChanging 的用法:在属性赋值之前调用,具体可见 Category 或 Product) /* * 为什么会减少内存使用量呢? * 因为 LINQ to SQL 更改跟踪是通过维护每个对象的两个副本进行工作的,第一个副本保存原始数据,第二个副本有程序更改,这样提交更新时 LINQ to SQL 就知道哪些数据被更改了,从而只提交这些被更改的数据 * INotifyPropertyChanging 接口允许应用程序在将修改后的数据提交到数据库前通知 DataContext,DataContext 可以将该通知用作创建副本的触发器,这样就不用保留第二个副本了,从而减少内存使用 */ public event PropertyChangingEventHandler PropertyChanging; protected void NotifyPropertyChanging(string propertyName) { if (PropertyChanging != null) { PropertyChanging(this, new PropertyChangingEventArgs(propertyName)); } } } }
Model层 - Category.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Data.Linq.Mapping; using System.Data.Linq; namespace Demo.LocalDatabase.Model { /* * Table - 将类标记为数据库中的一个表 * Index - 把类中的指定字段标记为索引字段 */