sqlce wp

WP7 ------------------- 本地数据库SQL Server CE

已有 474 次阅读 2012-2-21 10:26 |个人分类:WP7笔记|系统分类:Windows Phone数据库应用程序

终于在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. 支持的数据类型

数据类型

描述

bigint

Integer (whole number) data from –2^63 (–9,223,372,036,854,775,808) through 2^63–1 (9,223,372,036,854,775,807). Storage size is 8 bytes.

integer

Integer (whole number) data from –2^31 (–2,147,483,648) through 2^31–1 (2,147,483,647).

Storage size is 4 bytes.

smallint

Integer data from –32,768 to 32,767. Storage size is 2 bytes.

tinyint

Integer data from 0 to 255. Storage size is 1 byte.

bit

Integer data with a value of either 1 or 0.

Storage size is 1 bit.

numeric (p, s)

Synonyms:

decimal(p,s) and dec (p,s)

Fixed-precision and scale-numeric data from –10^38+1 through 10^38–1. The variable specifies precision and can vary between 1 and 38. The s variable specifies scale and can vary between 0 andp.

Storage size is 19 bytes.

money

Monetary data values from (–2^63/10000) (–922,337,203,685,477.5808) through 2^63–1 (922,337,203,685,477.5807), with accuracy to a ten-thousandth of a monetary unit. Storage size is 8 bytes.

float

Floating point number data from –1.79E +308 through 1.79E+308

Storage size is 8 bytes.

real

Floating precision number data from –3.40E+38 through 3.40E+38.

Storage size is 4 bytes.

datetime

Date and time data from January 1, 1753, to December 31, 9999, with an accuracy of one three-hundredth second, or 3.33 milliseconds. Values are rounded to increments of .000, .003, or .007 milliseconds.

Stored as two 4-byte integers. The first 4 bytes store the number of days before or after the base date, January 1, 1900. The base date is the system's reference date. Values for datetime earlier than January 1, 1753, are not permitted. The other 4 bytes store the time of day represented as the number of milliseconds after midnight. Seconds have a valid range of 0–59.

Format Example

yyyy/mm/dd hh:mm:ss 1947/08/15 03:33:20

mm/dd/yyyy hh:mm:ss 04/15/1947 03:33:20

dd mmm yyyy hh:mm:ss 15 Jan 1947 03:33:20

dd mmmm yyyy h:mm:ss 15 January 1947 03:33:20

national character(n)

Synonym:nchar(n)

Fixed-length Unicode data with a maximum length of 4000 characters. Default length = 1. Storage size, in bytes, is two times the number of characters entered.

national character varying(n)

Synonym:nvarchar(n)

Variable-length Unicode data with a length of 1 to 4000 characters. Default length = 1. Storage size, in bytes, is two times the number of characters entered.

ntext¹

Variable-length Unicode data with a maximum length of (2^30–2)/2 (536,870,911) characters. Storage size, in bytes, is two times the number of characters entered.

Note

ntext is no longer supported in string functions.

nchar

Fixed-length Unicode character data of n characters. n must be a value from 1 through 4,000. The storage size is two times n bytes.

binary(n)

Fixed-length binary data with a maximum length of 8000 bytes. Default length = 1.

Storage size is fixed, which is the length in bytes declared in the type.

varbinary(n)

Variable-length binary data with a maximum length of 8000 bytes. Default length = 1.

Storage size varies. It is the length of the value in bytes.

image¹

Variable-length binary data with a maximum length of 2^30–1 (1,073,741,823) bytes.

Storage is the length of the value in bytes.

uniqueidentifier

A globally unique identifier (GUID). Storage size is 16 bytes.

IDENTITY [(s, i)]

This is a property of a data column, not a distinct data type.

Only data columns of the integer data types can be used for identity columns. A table can have only one identity column. A seed and increment can be specified and the column cannot be updated.

s (seed) = starting value

i(increment) = increment value

ROWGUIDCOL

This is a property of a data column, not a distinct data type. It is a column in a table that is defined by using the uniqueidentifier data type. A table can have only one ROWGUIDCOL column.

Timestamp/rowversion

This is an automatically generated unique binary number.

Storage size is 8 bytes.

¹在SQL Server Compact 4.0中,当Ntext 和 image 数据超过256 bytes 时将会保存到一个新的数据页。这会影响到数据库的密度,因为SQL Server Compact 4.0 数据库是按页方式面不是按字节方式来压缩的。

在Windows Phone的第一个版本7.0版本里面是没有本地数据库支持的,要使用数据库只能够使用第三方的数据库组件。Windows Phone的本地数据库SQL Server CE是7.1版本即芒果更新的新特性,所以你要在应用程序中使用SQL Server CE数据库必须使用Windows Phone 7.1的API才行。
下面用一个实例演示如何使用SQL Server CE数据库。
(1)创建数据表以及数据库的数据上下文DateContent
先创建一个员工信息表,用于保存员工的名字和简介,员工表有一个自增的ID。
EmployeeTable.cs

  1. using System.Data.Linq.Mapping;
  2. using System.ComponentModel;
  3. namespace SQLServerDemo
  4. {
  5. [Table]
  6. public class EmployeeTable : INotifyPropertyChanged, INotifyPropertyChanging
  7. {
  8. // 定义员工表独立增长ID,设置为主键
  9. private int _employeeId;
  10. [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
  11. public int EmployeeID
  12. {
  13. get
  14. {
  15. return _employeeId;
  16. }
  17. set
  18. {
  19. if (_employeeId != value)
  20. {
  21. NotifyPropertyChanging("EmployeeID");
  22. _employeeId = value;
  23. NotifyPropertyChanged("EmployeeID");
  24. }
  25. }
  26. }
  27. // 定义员工名字字段
  28. private string _employeeName;
  29. [Column]
  30. public string EmployeeName
  31. {
  32. get
  33. {
  34. return _employeeName;
  35. }
  36. set
  37. {
  38. if (_employeeName != value)
  39. {
  40. NotifyPropertyChanging("EmployeeName");
  41. _employeeName = value;
  42. NotifyPropertyChanged("EmployeeName");
  43. }
  44. }
  45. }
  46. //定义员工简介字段
  47. private string _employeeDesc;
  48. [Column]
  49. public string EmployeeDesc
  50. {
  51. get
  52. {
  53. return _employeeDesc;
  54. }
  55. set
  56. {
  57. if (_employeeDesc != value)
  58. {
  59. NotifyPropertyChanging("EmployeeDesc");
  60. _employeeDesc = value;
  61. NotifyPropertyChanged("EmployeeDesc");
  62. }
  63. }
  64. }
  65. #region INotifyPropertyChanged Members
  66. public event PropertyChangedEventHandler PropertyChanged;
  67. //用来通知页面表的字段数据产生了改变
  68. private void NotifyPropertyChanged(string propertyName)
  69. {
  70. if (PropertyChanged != null)
  71. {
  72. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  73. }
  74. }
  75. #endregion
  76. #region INotifyPropertyChanging Members
  77. public event PropertyChangingEventHandler PropertyChanging;
  78. // 用来通知数据上下文表的字段数据将要产生改变
  79. private void NotifyPropertyChanging(string propertyName)
  80. {
  81. if (PropertyChanging != null)
  82. {
  83. PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
  84. }
  85. }
  86. #endregion
  87. }
  88. }
复制代码
创建数据库的DataContent,定义一个EmployeeDataContext类来继承DataContext,在EmployeeDataContext中定义数据库连接字符串,以及员工信息表。
EmployeeDataContext.cs
  1. using System.Data.Linq;
  2. namespace SQLServerDemo
  3. {
  4. public class EmployeeDataContext : DataContext
  5. {
  6. // 数据库链接字符串
  7. public static string DBConnectionString = "Data Source=isostore:/Employee.sdf";
  8. // 传递数据库连接字符串到DataContext基类
  9. public EmployeeDataContext(string connectionString)
  10. : base(connectionString)
  11. { }
  12. // 定义一个员工信息表
  13. public Table<EmployeeTable> Employees;
  14. }
  15. }
复制代码
(2) 创建页面数据绑定的集合
EmployeeCollection.cs
  1. using System.ComponentModel;
  2. using System.Collections.ObjectModel;
  3. namespace SQLServerDemo
  4. {
  5. //EmployeeCollection用于跟页面的数据绑定
  6. public class EmployeeCollection : INotifyPropertyChanged
  7. {
  8. //定义ObservableCollection来绑定页面的数据
  9. private ObservableCollection<EmployeeTable> _employeeTables;
  10. public ObservableCollection<EmployeeTable> EmployeeTables
  11. {
  12. get
  13. {
  14. return _employeeTables;
  15. }
  16. set
  17. {
  18. if (_employeeTables != value)
  19. {
  20. _employeeTables = value;
  21. NotifyPropertyChanged("EmployeeTables");
  22. }
  23. }
  24. }
  25. #region INotifyPropertyChanged Members
  26. public event PropertyChangedEventHandler PropertyChanged;
  27. //用于通知属性的改变
  28. private void NotifyPropertyChanged(string propertyName)
  29. {
  30. if (PropertyChanged != null)
  31. {
  32. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  33. }
  34. }
  35. #endregion
  36. }
  37. }
复制代码
(3)创建数据库,绑定数据,实现员工信息表的增删改查操作。
在App.xaml.cs中的程序加载事件中进行创建数据库
  1. private void Application_Launching(object sender, LaunchingEventArgs e)
  2. {
  3. //如果数据库不存在则创建一个数据库
  4. using (EmployeeDataContext db = new EmployeeDataContext(EmployeeDataContext.DBConnectionString))
  5. {
  6. if (db.DatabaseExists() == false)
  7. {
  8. //创建一个数据库
  9. db.CreateDatabase();
  10. }
  11. }
  12. }
复制代码
MainPage.xaml文件代码
  1. <phone:PhoneApplicationPage 
  2. x:Class="SQLServerDemo.MainPage"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  6. xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  7. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  8. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  9. mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
  10. FontFamily="{StaticResource PhoneFontFamilyNormal}"
  11. FontSize="{StaticResource PhoneFontSizeNormal}"
  12. Foreground="{StaticResource PhoneForegroundBrush}"
  13. SupportedOrientations="Portrait" Orientation="Portrait"
  14. shell:SystemTray.IsVisible="True">
  15. <Grid x:Name="LayoutRoot" Background="Transparent">
  16. <Grid.RowDefinitions>
  17. <RowDefinition Height="Auto"/>
  18. <RowDefinition Height="*"/>
  19. </Grid.RowDefinitions>
  20. <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
  21. <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
  22. <TextBlock x:Name="PageTitle" Text="SQL Server" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
  23. </StackPanel>
  24. <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  25. <Grid Margin="0,0,0,385">
  26. <Grid.ColumnDefinitions>
  27. <ColumnDefinition Width="*" />
  28. <ColumnDefinition Width="Auto" />
  29. </Grid.ColumnDefinitions>
  30. <TextBlock FontSize="30" Height="37" HorizontalAlignment="Left" Margin="12,18,0,0" Name="textBlock1" Text="员工名字:" VerticalAlignment="Top" />
  31. <TextBox Name="name" Text="" Margin="145,0,6,144" />
  32. <TextBlock FontSize="30" Height="52" HorizontalAlignment="Left" Margin="18,74,0,0" Name="textBlock2" Text="简介:" VerticalAlignment="Top" />
  33. <TextBox Height="79" HorizontalAlignment="Left" Margin="93,65,0,0" Name="desc" Text="" VerticalAlignment="Top" Width="357" />
  34. <Button 
  35. Content="保存" x:Name="addButton"
  36. Click="addButton_Click" Margin="219,132,6,6" />
  37. </Grid>
  38. <ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding EmployeeTables}" Margin="12,241,12,0" Width="440">
  39. <ListBox.ItemTemplate>
  40. <DataTemplate>
  41. <Grid HorizontalAlignment="Stretch" Width="440">
  42. <Grid.ColumnDefinitions>
  43. <ColumnDefinition Width="50" />
  44. <ColumnDefinition Width="*" />
  45. <ColumnDefinition Width="100" />
  46. </Grid.ColumnDefinitions>
  47. <TextBlock
  48. Text="{Binding EmployeeName}"
  49. FontSize="{StaticResource PhoneFontSizeLarge}"
  50. Grid.Column="1"
  51. VerticalAlignment="Center"/>
  52. <Button
  53. Grid.Column="2"
  54. x:Name="deleteButton"
  55. BorderThickness="0" 
  56. Margin="0"
  57. Click="deleteButton_Click"
  58. Content="删除">
  59. </Button>
  60. <Button
  61. Grid.Column="1"
  62. x:Name="editButton"
  63. BorderThickness="0" 
  64. Margin="209,0,81,0"
  65. Click="editButton_Click"
  66. Content="编辑" Grid.ColumnSpan="2">
  67. </Button>
  68. </Grid>
  69. </DataTemplate>
  70. </ListBox.ItemTemplate> 
  71. </ListBox> 
  72. </Grid>
  73. </Grid>
  74. </phone:PhoneApplicationPage>
复制代码
MainPage.xaml.cs文件代码
  1. using System.Linq;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using Microsoft.Phone.Controls;
  5. using System.Collections.ObjectModel;
  6. namespace SQLServerDemo
  7. {
  8. public partial class MainPage : PhoneApplicationPage
  9. {
  10. // 创建DataContext实例用于用于操作本地的数据库
  11. private EmployeeDataContext employeeDB;
  12. private EmployeeCollection employeeCol = new EmployeeCollection();
  13. public MainPage()
  14. {
  15. InitializeComponent();
  16. //连接数据库并初始化DataContext实例
  17. employeeDB = new EmployeeDataContext(EmployeeDataContext.DBConnectionString);
  18. // 使用Linq查询语句查询EmployeeTable表的所有数据
  19. var employeesInDB = from EmployeeTable employee in employeeDB.Employees
  20. select employee;
  21. // 将查询的结果返回到页面数据绑定的集合里面
  22. employeeCol.EmployeeTables = new ObservableCollection<EmployeeTable>(employeesInDB);
  23. //赋值给当前页面的DataContext用于数据绑定
  24. this.DataContext = employeeCol;
  25. }
  26. /// <summary>
  27. /// 删除操作
  28. /// </summary>
  29. /// <param name="sender"></param>
  30. /// <param name="e"></param>
  31. private void deleteButton_Click(object sender, RoutedEventArgs e)
  32. {
  33. // 获取单击的按钮实例
  34. var button = sender as Button;
  35. if (button != null)
  36. {
  37. //获取当前按钮绑定的DataContext,即当前的删除的EmployeeTable实例
  38. EmployeeTable employeeForDelete = button.DataContext as EmployeeTable;
  39. //移除绑定集合里面要删除的EmployeeTable记录
  40. employeeCol.EmployeeTables.Remove(employeeForDelete);
  41. // 移除数据库里面要删除的EmployeeTable记录
  42. employeeDB.Employees.DeleteOnSubmit(employeeForDelete);
  43. //保存数据库的改变
  44. employeeDB.SubmitChanges();
  45. }
  46. }
  47. /// <summary>
  48. /// 保存操作,处理新增和编辑员工信息
  49. /// </summary>
  50. /// <param name="sender"></param>
  51. /// <param name="e"></param>
  52. private void addButton_Click(object sender, RoutedEventArgs e)
  53. {
  54. //控制员工名字和简介不能为空
  55. if (name.Text != "" && desc.Text != "")
  56. {
  57. if (State.Count>0 && State["employee"] != null )//编辑状态
  58. {
  59. //获取编辑的EmployeeTable对象
  60. EmployeeTable employee = (EmployeeTable)State["employee"];
  61. employee.EmployeeName = name.Text;
  62. employee.EmployeeDesc = desc.Text;
  63. //保存数据库的改变
  64. employeeDB.SubmitChanges();
  65. //添加绑定集合的数据,因为在单击编辑的时候移除了
  66. employeeCol.EmployeeTables.Add(employee);
  67. State["employee"] = null;
  68. }
  69. else//新增状态
  70. {
  71. //创建一条表的数据
  72. EmployeeTable newEmployee = new EmployeeTable { EmployeeName = name.Text, EmployeeDesc = desc.Text };
  73. //添加绑定集合的数据
  74. employeeCol.EmployeeTables.Add(newEmployee);
  75. //插入数据库
  76. employeeDB.Employees.InsertOnSubmit(newEmployee);
  77. //保存数据库的改变
  78. employeeDB.SubmitChanges();
  79. }
  80. name.Text = "";
  81. desc.Text = "";
  82. }
  83. else
  84. {
  85. MessageBox.Show("姓名和简介不能为空!");
  86. }
  87. }
  88. /// <summary>
  89. /// 编辑操作
  90. /// </summary>
  91. /// <param name="sender"></param>
  92. /// <param name="e"></param>
  93. private void editButton_Click(object sender, RoutedEventArgs e)
  94. {
  95. // 获取单击的按钮实例
  96. var button = sender as Button;
  97. if (button != null)
  98. {
  99. //获取当前按钮绑定的DataContext,即当前的编辑的EmployeeTable实例
  100. EmployeeTable employeeForEdit = button.DataContext as EmployeeTable;
  101. name.Text = employeeForEdit.EmployeeName;
  102. desc.Text = employeeForEdit.EmployeeDesc;
  103. //将需要编辑的表实例存储在State里面
  104. State["employee"] = employeeForEdit;
  105. employeeCol.EmployeeTables.Remove(employeeForEdit);
  106. }
  107. }
  108. }
  109. }
复制代码
运行效果如下:
<ignore_js_op>
原文地址:https://www.cnblogs.com/songtzu/p/2631521.html