如何在WP8中进行数据存储,你首先想到应该是独立存储,但是独立存储似乎存储文件更方便,如果我们希望像处理对象的形式,该怎么办呢,答案就是Sql Server CE。

Sql Server CE并不是新鲜东西,它是专门用在移动端的一个工具,它和SQLServer有很大的不同,SQLServer中我们使用Sql语句,而Sql Server CE则要使用Linq处理。

一、创建表

 /// <summary>
/// 员工表
/// </summary>
[Table]
class EmployeeTable : INotifyPropertyChanged, INotifyPropertyChanging
{ private int _employeeId;
/// <summary>
/// 员工Id
/// </summary>
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int EmployeeId
{
get { return _employeeId; }
set
{
if (_employeeId != value)
{
OnPropertyChanging("EmployeeId");
_employeeId = value;
OnPropertyChanged("EmployeeId");
}
}
} private string _employeeName;
/// <summary>
/// 员工名称
/// </summary>
[Column]
public string EmployeeName
{
get { return _employeeName; }
set
{
if (_employeeName != value)
{
OnPropertyChanging("EmployeeName");
_employeeName = value;
OnPropertyChanged("EmployeeName");
}
}
} private string _employeeDesc;
/// <summary>
/// 员工简介
/// </summary>
[Column]
public string EmployeeDesc
{
get { return _employeeDesc; }
set
{
if (_employeeDesc != value)
{
OnPropertyChanging("EmployeeDesc");
_employeeDesc = value;
OnPropertyChanged("EmployeeDesc");
}
}
} public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangingEventHandler PropertyChanging;
private void OnPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
}

一张员工表,有三个属性。类需要加上Table特性,如果你使用过Linq to sql,那么整个特性应该是见过的;另外就是对每个属性需要使用Column特性进行标注;最最重要的一点,类要实现自INotifyPropertyChanged, INotifyPropertyChanging,这两个接口主要是为了通知,同时在类中实现着两个接口的时间即可,并且在属性的Set中进行调用就ok了。
二、上下文对象类(用于操作数据,和数据库交互)

   /// <summary>
/// 上下文对象类
/// </summary>
class EmployeeDataContext:DataContext
{
//数据库连接字符串
public static string DBConnectionString = "Data Source=isostore:/Employee.sdf";
public EmployeeDataContext(string connectionString)
: base(connectionString) { }
//员工信息表
public Table<EmployeeTable> Employees;
}

就是一般的类,只不过继承自DataContext,这个和Linq to sql中的上下文对象同一个基类。类中有一个连接字符串属性,同时构造函数支持传入一个连接字符串,另外就是有我们上文中创建的表的一个Table类型的集合,表示一个集合类型。

三、数据列表类(此类大家也可以没有,因为对于集合的处理,大家可以根据自己的需要进行修改)

 /// <summary>
/// 列表集合
/// </summary>
class EmployeeCollection : INotifyPropertyChanged
{
private ObservableCollection<EmployeeTable> _employeeTables;
/// <summary>
/// 员工列表集合
/// </summary>
public ObservableCollection<EmployeeTable> EmployeeTables
{
get { return _employeeTables; }
set
{
if (_employeeTables != value)
{
_employeeTables = value;
OnPropertyChanged("EmployeeTables");
}
}
} public void UpdateEmployee(EmployeeTable employee)
{
var oldEmployee = EmployeeTables.Where(e => e.EmployeeId == employee.EmployeeId).FirstOrDefault();
oldEmployee.EmployeeName = employee.EmployeeName;
oldEmployee.EmployeeDesc = employee.EmployeeDesc;
} public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

类中只有一个Employee的集合和一个用于更新对象的方法,以及实现自INotifyPropertyChanged的内容。

四、使用

     <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid Margin="0,0,0,385">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock FontSize="30" Height="37" HorizontalAlignment="Left" Margin="12,18,0,0" Name="textBlock1" Text="员工名字:" VerticalAlignment="Top" />
<TextBox Name="name" Text="" Margin="145,0,6,144" /> <TextBlock FontSize="30" Height="52" HorizontalAlignment="Left" Margin="18,74,0,0" Name="textBlock2" Text="简介:" VerticalAlignment="Top" />
<TextBox Height="79" HorizontalAlignment="Left" Margin="93,65,0,0" Name="desc" Text="" VerticalAlignment="Top" Width="357" /> <Button
Content="保存" x:Name="saveButton"
Click="saveButton_Click" Margin="219,132,6,6" /> </Grid> <ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding EmployeeTables}" Margin="12,241,12,0" Width="440">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Width="440">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions> <TextBlock
Text="{Binding EmployeeName}"
FontSize="{StaticResource PhoneFontSizeLarge}"
Grid.Column="1"
VerticalAlignment="Center"/>
<Button
Grid.Column="2"
x:Name="deleteButton"
BorderThickness="0"
Margin="0"
Click="deleteButton_Click"
Content="删除">
</Button>
<Button
Grid.Column="1"
x:Name="editButton"
BorderThickness="0"
Margin="209,0,81,0"
Click="editButton_Click"
Content="编辑" Grid.ColumnSpan="2">
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

后台代码:

 public partial class MainPage : PhoneApplicationPage
{
//上下文对象
private EmployeeDataContext employeeDB;
//列表集合对象
private EmployeeCollection employeeCollection = new EmployeeCollection();
// Constructor
public MainPage()
{
InitializeComponent();
//连接数据库并初始化DataContext实例
employeeDB = new EmployeeDataContext(EmployeeDataContext.DBConnectionString);
//查询所有的记录
var employeeQry = from e in employeeDB.Employees select e; employeeCollection.EmployeeTables=new ObservableCollection<EmployeeTable>(employeeQry);
//设置当前页面的上下文对象为列表集合
this.DataContext = employeeCollection;
} /// <summary>
/// 删除
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void deleteButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
if (button!=null)
{
//得到当前按钮所绑定的数据
EmployeeTable employee = button.DataContext as EmployeeTable;
//从集合中移除
employeeCollection.EmployeeTables.Remove(employee);
//从数据库中移除
employeeDB.Employees.DeleteOnSubmit(employee);
//更新到数据库
employeeDB.SubmitChanges();
}
} /// <summary>
/// 编辑
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void editButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
if (button!=null)
{
//得到当前按钮绑定的数据
EmployeeTable employ = button.DataContext as EmployeeTable;
//将名称和简介设置为文本框的值
name.Text = employ.EmployeeName;
desc.Text = employ.EmployeeDesc;
//将当前编辑的对象放置在State中,用于保存时候使用
State["employee"] = employ;
//将当前对象从集合中移除
employeeCollection.UpdateEmployee(employ);
// employeeCollection.EmployeeTables.Remove(employ);
}
} /// <summary>
/// 保存
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void saveButton_Click(object sender, RoutedEventArgs e)
{
if (name.Text != "" && desc.Text != "")
{
//如果当前的State不为空,并且存在Employee,则为编辑
if (State.Count > && State["employee"] != null)
{
//得到State中的对象
EmployeeTable employ = (EmployeeTable)State["employee"];
//将文本框的值设置给对象
employ.EmployeeName = name.Text;
employ.EmployeeDesc = desc.Text;
//将数据保存到数据库
employeeDB.SubmitChanges();
// employeeCollection.EmployeeTables.Add(employ);
State["employee"] = null; }
//新增
else
{
//创建Employee对象
EmployeeTable employee = new EmployeeTable { EmployeeName = name.Text, EmployeeDesc = desc.Text };
//将Employee放入集合中
employeeCollection.EmployeeTables.Add(employee);
//将Employee添加到数据库
employeeDB.Employees.InsertOnSubmit(employee);
//将数据更新到数据库
employeeDB.SubmitChanges();
} name.Text = "";
desc.Text = "";
}
else
{
MessageBox.Show("姓名和简介不能为空");
}
}
}

五、迟到的创建数据库
细心的童鞋会发现,为什么木有创建数据库的过程,如下:

 private void Application_Launching(object sender, LaunchingEventArgs e)
{
using (EmployeeDataContext db=new EmployeeDataContext (EmployeeDataContext.DBConnectionString))
{
if (db.DatabaseExists()==false)
{
db.CreateDatabase();
}
}
}

在App.xaml.cs中放入上述代码即可,也就是创建了一个数据库。

Tips:数据库文件同样是在独立存储空间中。

WP之Sql Server CE数据库的更多相关文章

  1. Windows Phone 8 SQL Server CE 数据库

    员工信息表 EmployeeTable.cs using System.Data.Linq.Mapping; using System.ComponentModel; namespace SQLSer ...

  2. 让PDF.NET支持不同版本的SQL Server Compact数据库

    最近项目中需要用到嵌入式数据库,我们选用的数据开发框架是PDF.NET(http://www.pwmis.com/SqlMap/),之前的博文已经总结了让PDF.NET支持最新的SQLite,今天我们 ...

  3. Linux下使用FreeTDS访问MS SQL Server 2005数据库(包含C测试源码)

    Linux下使用FreeTDS访问MS SQL Server 2005数据库(包含C测试源码) http://blog.csdn.net/helonsy/article/details/7207497 ...

  4. 如何转换SQL Server 2008数据库到SQL Server 2005

        背景介绍: 公司一套系统使用的是SQL SERVER 2008数据库,突然一天收到邮件,需要将这套系统部署到各个不同地方(海外)的工厂,需要在各个工厂部署该数据库,等我将准备工作做好,整理文档 ...

  5. SQL SERVER 2008数据库各版本功能对比

    微软SQL SERVER 2008数据库有6个版本,分别是数据中心版.企业版.标准版.Web版.工作组版.简易版,有时候购买的时候或需要使用某项功能时,需要了解各个版本的区别,功能差异,很多时候,大部 ...

  6. SQL Server附加数据库时报1813错误的解决方案

    SQL Server附加数据库时报1813错误的解决方案   无法打开新数据库 'ASR'.CREATE DATABASE 中止. 文件激活失败.物理文件名称'E:\SqlServer\MSSQL\D ...

  7. SQL Server附加数据库问题

    SQL Server附加数据库时,遇到如下问题:“如果升级全文目录,请单加“添加目录”,然后找到它并选择它.基于全文升级选项,全文索引将为“已导入”.” 解决方法: 选择数据库文件所在目录,右键-&g ...

  8. SQL Server附加数据库出现错误5123的正确解决方法

    因为自己有一本基于SQL Server 2005的数据库教程,里边使用的示例数据库是AdventureWorks for SQL Server 2005,而我的机子上装的是SQL Server 200 ...

  9. 通过SQL Server 2008数据库复制实现数据库同步备份

    SQL Server 2008数据库复制是通过发布/订阅的机制进行多台服务器之间的数据同步,我们把它用于数据库的同步备份.这里的同步备份指的是备份服务器与主服务器进行 实时数据同步,正常情况下只使用主 ...

随机推荐

  1. 每日一“酷”之Queue

    Queue—线程安全的FIFO实现 作用:提供一个线程安全的FIFO实现 Queue模块提供了一个适用于多线程编程的先进先出(first-in,first-out)数据结构,可以用来在生产者和消费者线 ...

  2. [转] c和python利用setsockopt获得端口重用

    假如端口被socket使用过,并且利用socket.close()来关闭连接,但此时端口还没有释放,要经过一个TIME_WAIT的过程之后才能使用.为了实现端口的马上复用,可以选择setsockopt ...

  3. Python - python不是内部或外部命令

    [方法一]我的电脑->属性->高级->环境变量->系统变量   在系统变量里找到PATH,双击PATH,在结尾加上 ";C:\Python26"(不要引号) ...

  4. VBS基础篇 - 堆栈

    VBS中的堆栈需要使用System.Collections.Stack '建立堆栈 Dim Stk : Set Stk = CreateObject("System.Collections. ...

  5. LintCode-Implement Iterator of Binary Search Tree

    Design an iterator over a binary search tree with the following properties: Elements are visited in ...

  6. 3573: [Hnoi2014]米特运输 - BZOJ

    Description米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题.    D星上有N个城市,我们将其顺序编号为1到N,1号 ...

  7. java 非法字符过滤 , 半角/全角替换

    java 非法字符过滤 , 半角/全角替换 package mjorcen.netty.test1; import java.io.UnsupportedEncodingException; publ ...

  8. Eclipse 安装热部署JRebel

    开发环境 sts-3.7.2.RELEASE 安装步骤 1.打开应市场 2.搜索JRebel并进行下载 3.下载完成后点击JReble Configuation进入

  9. MyEclipse2015破解版_MyEclipse 2015 stable 2.0 稳定版 破解日志

    前言:在MyEclipse 2015 Stable 1.0下载安装破解日志(http://www.cnblogs.com/wql025/p/5161979.html)一文中,笔者主要讲述了该版本的破解 ...

  10. 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

    // ConsoleApplication2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "stdafx.h ...