终于在Wp7.1中加入了数据库,使保存、查找、插入数据不再痛苦。在WP7中如果要做到这些,要么使用XML自已实现,要么使用第三方数据库,但是第三方数据库要么性能不好,要么占用空间太大,要么收费,现在总算有原生的本地数据库了。
1. 架构
这个本地数据库,不能直接支持Transact-SQL,需要通过LINQ to SQL 对象模型作为Proxy来操作数据库,为此引入了一个新的类System.Data.Linq.DataContext。这与windows mobile上的SQL CE有了很大的差别。
2. LINQ to SQL
在Windows phone中,LINQ to SQL既不能直接支持执行Data Definition Language(DDL)也不支持Data Modeling Language(DML),另外也不能直接访问ADO.NET。只能支持Microsoft SQL Server Compact Edition (SQL CE)的数据类型。并且需要通过DataContext方式来操来数据库。
3. 支持的数据类型
在SQL Server Compact 4.0中,当Ntext 和 image 数据超过256 bytes 时将会保存到一个新的数据页。这会影响到数据库的密度,因为SQL Server Compact 4.0 数据库是按页方式面不是按字节方式来压缩的。
4. 创建工程
新建一个Windows Phone工程,最好是MVVM工程,也就是选择新建工程中的Windows Phone Databound Application 模板直接生成或者手工创建MVVM工程。创建好后,将System.Data.Linq命名空间引入到工程。这个命名空间所在位置\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone71中。
5. 创建数据库
新建一个类继承System.Data.Linq.DataContext类,这样就可以用这个类来控制数据库了。
{
public const string ConnectionStr = "Data Source=isostore:/MyDB.sdf";
public Table<MyTable> Rows;
public MyDataContext()
: base(ConnectionStr)
{
}
}
在这个类中同时创建数据库表类。
{
private int _index;
[Column(IsPrimaryKey = true, CanBeNull = false, IsDbGenerated = true, DbType = "INT NOT NULL Identity", AutoSync=AutoSync.OnInsert)]
public int Index
{
get
{
return _index;
}
set
{
if (_index != value)
{
NotifyPropertyChanging("Index");
_index = value;
NotifyPropertyChanged("Index");
}
}
}
private string _name;
[Column]
public string Name
{
get
{
return _name;
}
set
{
NotifyPropertyChanging("Name");
_name = value;
NotifyPropertyChanged("Name");
}
}
private String _gen;
[Column]
public String Gen
{
get
{
return _gen;
}
set
{
NotifyPropertyChanging("Gen");
_gen = value;
NotifyPropertyChanged("Gen");
}
}
private int _age;
[Column]
public int Age
{
get
{
return _age;
}
set
{
NotifyPropertyChanging("Age");
_age = value;
NotifyPropertyChanged("Age");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}
6. 操作数据库
新建一个ViewModel类,在这个类中实现数据库的操作。在这个类中实现了对数据的选择、保存、更新和删除。在对数据库的操作因为不能直接使用Transact_SQL,所以操作都是通过LINQ来完成的。
MyDataContext _DB;
{
if (IsAddedToDB)
{
if (_DB.DatabaseExists())
{
IEnumerator<MyTable> enumerator = _DB.Rows.GetEnumerator();
while (enumerator.MoveNext())
{
this.Items.Add(enumerator.Current);
}
IsAddedToDB = false;
}
}
}
public bool SaveData(MyTable table)
{
try
{
this.Items.Add(table);
_DB.Rows.InsertOnSubmit(table);
_DB.SubmitChanges();
}
catch (Exception e)
{
return false;
}
return true;
}
public bool DeleteData(MyTable table)
{
try
{
if (_DB.DatabaseExists())
{
_DB.Rows.DeleteOnSubmit(table);
_DB.SubmitChanges();
this.Items.Remove(table);
}
}
catch (Exception e)
{
return false;
}
return true;
}
public bool UpdateData(MyTable source, MyTable dest)
{
try
{
var tables = from item in this.Items where (int)item.Index == source.Index select item;
foreach (MyTable mt in tables)
{
mt.Name = dest.Name;
mt.Age = dest.Age;
mt.Gen = dest.Gen;
break;
}
MyTable table = _DB.Rows.GetOriginalEntityState(source);
table.Name = dest.Name;
table.Age = dest.Age;
table.Gen = dest.Gen;
_DB.SubmitChanges();
}
catch (Exception e)
{
return false;
}
return true;
}
1. 架构
这个本地数据库,不能直接支持Transact-SQL,需要通过LINQ to SQL 对象模型作为Proxy来操作数据库,为此引入了一个新的类System.Data.Linq.DataContext。这与windows mobile上的SQL CE有了很大的差别。
2. LINQ to SQL
在Windows phone中,LINQ to SQL既不能直接支持执行Data Definition Language(DDL)也不支持Data Modeling Language(DML),另外也不能直接访问ADO.NET。只能支持Microsoft SQL Server Compact Edition (SQL CE)的数据类型。并且需要通过DataContext方式来操来数据库。
3. 支持的数据类型
在SQL Server Compact 4.0中,当Ntext 和 image 数据超过256 bytes 时将会保存到一个新的数据页。这会影响到数据库的密度,因为SQL Server Compact 4.0 数据库是按页方式面不是按字节方式来压缩的。
4. 创建工程
新建一个Windows Phone工程,最好是MVVM工程,也就是选择新建工程中的Windows Phone Databound Application 模板直接生成或者手工创建MVVM工程。创建好后,将System.Data.Linq命名空间引入到工程。这个命名空间所在位置\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone71中。
5. 创建数据库
新建一个类继承System.Data.Linq.DataContext类,这样就可以用这个类来控制数据库了。
{
public const string ConnectionStr = "Data Source=isostore:/MyDB.sdf";
public Table<MyTable> Rows;
public MyDataContext()
: base(ConnectionStr)
{
}
}
在这个类中同时创建数据库表类。
{
private int _index;
[Column(IsPrimaryKey = true, CanBeNull = false, IsDbGenerated = true, DbType = "INT NOT NULL Identity", AutoSync=AutoSync.OnInsert)]
public int Index
{
get
{
return _index;
}
set
{
if (_index != value)
{
NotifyPropertyChanging("Index");
_index = value;
NotifyPropertyChanged("Index");
}
}
}
private string _name;
[Column]
public string Name
{
get
{
return _name;
}
set
{
NotifyPropertyChanging("Name");
_name = value;
NotifyPropertyChanged("Name");
}
}
private String _gen;
[Column]
public String Gen
{
get
{
return _gen;
}
set
{
NotifyPropertyChanging("Gen");
_gen = value;
NotifyPropertyChanged("Gen");
}
}
private int _age;
[Column]
public int Age
{
get
{
return _age;
}
set
{
NotifyPropertyChanging("Age");
_age = value;
NotifyPropertyChanged("Age");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}
6. 操作数据库
新建一个ViewModel类,在这个类中实现数据库的操作。在这个类中实现了对数据的选择、保存、更新和删除。在对数据库的操作因为不能直接使用Transact_SQL,所以操作都是通过LINQ来完成的。
MyDataContext _DB;
{
if (IsAddedToDB)
{
if (_DB.DatabaseExists())
{
IEnumerator<MyTable> enumerator = _DB.Rows.GetEnumerator();
while (enumerator.MoveNext())
{
this.Items.Add(enumerator.Current);
}
IsAddedToDB = false;
}
}
}
public bool SaveData(MyTable table)
{
try
{
this.Items.Add(table);
_DB.Rows.InsertOnSubmit(table);
_DB.SubmitChanges();
}
catch (Exception e)
{
return false;
}
return true;
}
public bool DeleteData(MyTable table)
{
try
{
if (_DB.DatabaseExists())
{
_DB.Rows.DeleteOnSubmit(table);
_DB.SubmitChanges();
this.Items.Remove(table);
}
}
catch (Exception e)
{
return false;
}
return true;
}
public bool UpdateData(MyTable source, MyTable dest)
{
try
{
var tables = from item in this.Items where (int)item.Index == source.Index select item;
foreach (MyTable mt in tables)
{
mt.Name = dest.Name;
mt.Age = dest.Age;
mt.Gen = dest.Gen;
break;
}
MyTable table = _DB.Rows.GetOriginalEntityState(source);
table.Name = dest.Name;
table.Age = dest.Age;
table.Gen = dest.Gen;
_DB.SubmitChanges();
}
catch (Exception e)
{
return false;
}
return true;
}