原文地址:http://www.codeproject.com/Articles/1097179/SQLite-with-Xamarin-Forms-Step-by-Step-guide
SQLite是移动常见关系型数据库,轻便好用。下面我们就一步步实现xamarin对于sqlite的操作。
创建项目添加NuGet引用
我们采用第三方由oysteinkrog创建的"SQLite-Net-PCL"引用。
由于数据库文件的位置在不同平台存在差异,并且SQLite-Net-PCL不能自动初始化数据库连接对象,所以需要采用历来服务来加载。
Forms interface create
创建Forms的接口文件如下:
using SQLite.Net;
?
namespace SQLiteEx
{
public
interface ISQLite
{
SQLiteConnection GetConnection();
}
}
?
SQLiteService?
创建一个名为‘class文件SQLiteService?‘实施‘?ISQLite?"接口和写本"实施的getConnection像下面给出的代码每个特定平台的代码":对于新数据库:当我们创建应用程序本身的一个数据库那么第一次下面的代码将被使用。?
Android:
using System;
using Xamarin.Forms;
using SQLiteEx.Droid;
using System.IO;
?
[assembly: Dependency(typeof(SqliteService))]
namespace SQLiteEx.Droid
{
public
class SqliteService : ISQLite
{
public SqliteService() { }
?
#region ISQLite implementation
public SQLite.Net.SQLiteConnection GetConnection()
{
var sqliteFilename = "SQLiteEx.db3";
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
var path = Path.Combine(documentsPath, sqliteFilename);
Console.WriteLine(path);
if (!File.Exists(path)) File.Create(path);
var plat = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
var conn = new SQLite.Net.SQLiteConnection(plat, path);
// Return the database connection
return conn;
}
?
#endregion
?
?
}
}
?
IOS
using SQLiteEx.iOS;
using System;
using System.IO;
using Xamarin.Forms;
?
[assembly: Dependency(typeof(SqliteService))]
namespace SQLiteEx.iOS
{
public
class SqliteService : ISQLite
{
public SqliteService()
{
}
#region ISQLite implementation
public SQLite.Net.SQLiteConnection GetConnection()
{
var sqliteFilename = "SQLiteEx.db3";
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
string libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder
var path = Path.Combine(libraryPath, sqliteFilename);
?
// This is where we copy in the prepopulated database
Console.WriteLine(path);
if (!File.Exists(path))
{
File.Create(path);
}
?
var plat = new SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS();
var conn = new SQLite.Net.SQLiteConnection(plat, path);
?
// Return the database connection
return conn;
}
#endregion
}
}
?
对于预创建数据库:在一些应用场合可能有该数据库是一个要求预先填充了一些数据,我们将使用相同的应用程序。在这种情况下首先在遵循特定平台的项目中提到的地点将数据库文件复制,然后使用按照"SQLiteService‘类代码的Android:复制数据库文件中的"资源\原始"?Android平台的项目文件夹中
修改代码如下:
using System;
using Xamarin.Forms;
using SQLiteEx.Droid;
using System.IO;
?
[assembly: Dependency(typeof(SqliteService))]
namespace SQLiteEx.Droid
{
????
????public
class SqliteService : ISQLite {
?
????????public SqliteService () {}
?
????????#region ISQLite implementation????
????????public SQLite.Net.SQLiteConnection GetConnection ()
????????{
????????????var sqliteFilename = "SQLiteEx.db3";
????????????string documentsPath = System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal); // Documents folder
????????????var path = Path.Combine(documentsPath, sqliteFilename);
?
????????????// This is where we copy in the prepopulated database
????????????Console.WriteLine (path);
????????????if (!File.Exists(path))
????????????{
????????????????var s = Forms.Context.Resources.OpenRawResource(Resource.Raw.APGameDb); // RESOURCE NAME ###
?
????????????????// create a write stream
????????????????FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
????????????????// write to the stream
????????????????ReadWriteStream(s, writeStream);
????????????}
?
????????????var plat = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
????????????var conn = new SQLite.Net.SQLiteConnection(plat, path);
?
????????????// Return the database connection
????????????return conn;
????????}
????????#endregion
?
?
????????void ReadWriteStream(Stream readStream, Stream writeStream)
????????{
????????????int Length = 256;
????????????Byte[] buffer = new
Byte[Length];
????????????int bytesRead = readStream.Read(buffer, 0, Length);
????????????// write the required bytes
????????????while (bytesRead > 0)
????????????{
????????????????writeStream.Write(buffer, 0, bytesRead);
????????????????bytesRead = readStream.Read(buffer, 0, Length);
????????????}
????????????readStream.Close();
????????????writeStream.Close();
????????}
?
?
????}
}
?
var s = Forms.Context.Resources.OpenRawResource(Resource.Raw.APGameDb); // RESOURCE NAME ###
如果这句话存在疑问,证明没有默认数据库文件
我创建了一个文件名sxb.db3 与上文的var sqliteFilename = "SQLiteEx.db3"; 文件名不同
大家自行处理即可,
修改生成操作作为androidResource 既可以在代码中使用了。
创建命名为"PCL项目类DataAccess"。这个类将包含所有应用程序的数据访问代码
using SQLite.Net;
using Xamarin.Forms;
?
namespace SQLiteEx
{
public
class DataAccess
{
SQLiteConnection dbConn;
public DataAccess()
{
dbConn = DependencyService.Get<ISQLite>().GetConnection();
// create the table(s)
dbConn.CreateTable<Employee>();
}
public List<Employee> GetAllEmployees()
{
return dbConn.Query<Employee>("Select * From [Employee]");
}
public
int SaveEmployee(Employee aEmployee)
{
return dbConn.Insert(aEmployee);
}
public
int DeleteEmployee(Employee aEmployee)
{
return dbConn.Delete(aEmployee);
}
public
int EditEmployee(Employee aEmployee)
{
return dbConn.Update(aEmployee);
}
}
}
?
通过DataAccess针对员工表进行操作。其次,代码创建的表没有构造函数,为此,我们将有即使我们使用的是预创建数据库的方法,在数据库中的表会自动检查给,如果不存在,创建它。
创建普通老式CLR对象(POCO)。
例如,‘?员工?‘为‘上面给出的表类数据访问?"类。
员工:
using SQLite.Net.Attributes;
using System;
?
namespace SQLiteEx
{
public
class Employee
{
[PrimaryKey, AutoIncrement]
public
long EmpId
{ get; set; }
[NotNull]
public
string EmpName
{ get; set; }
public
string Designation
{ get; set; }
public
string Department
{ get; set; }
public
string Qualification
{ get; set; }
}
}
创建"的静态对象属性数据访问的‘?应用程序像下面的代码‘类。这将使我们能够使用来自应用程序的任何屏幕上操作数据。
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
?
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace SQLiteEx
{
public
class App : Application
{
static DataAccess dbUtils;
public App()
{
// The root page of your application
MainPage = new NavigationPage(new ManageEmployee());
}
public
static DataAccess DAUtil
{
get
{
if (dbUtils == null)
{
dbUtils = new DataAccess();
}
return dbUtils;
}
}
protected
override
void OnStart()
{
// Handle when your app starts
}
?
protected
override
void OnSleep()
{
// Handle when your app sleeps
}
?
protected
override
void OnResume()
{
// Handle when your app resumes
}
}
}
?
Ios版本
AppDelegate
中增加DataAccess
属性同上
这样就完成了使用SQLite数据库坚持应用程序的数据应用的基本结构。
现在,让我们创建示例应用程序看到CRUD操作code.The应用将包含以下屏幕的屏幕:
- 管理员工
- 添加员工
- 显示员工详细信息
- 编辑员工
Xaml
?
管理员工:此屏幕是应用程序的主屏幕上,它会显示目前员工名单,并给予一个选项,以添加新的员工,查看员工的详细信息和管理部门。此页面的XAML代码将是这样的:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SQLiteEx.ManageEmployee" Title="Manage Employees" >
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<ContentPage.Content>
<ListView x:Name="lstData" HasUnevenRows="false" Header="Header Value" Footer="Footer" ItemSelected="OnSelection" >
<ListView.HeaderTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" BackgroundColor="Blue" Padding="5,5,5,5">
<Label Text="Name" FontSize="Medium" FontAttributes="Bold" TextColor="White"/>
<Label Text="Designation" FontSize="Medium" FontAttributes="Bold" TextColor="White"/>
<Label Text="Department" FontSize="Medium" FontAttributes="Bold" TextColor="White"/>
</StackLayout>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="5,5,5,5">
<Label Text="{Binding EmpName}" FontSize="Medium" />
<Label Text="{Binding Designation}" FontSize="Medium" />
<Label Text="{Binding Department}" FontSize="Medium" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.FooterTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Padding="5,5,5,5">
<Button Text="Add New Employee" Clicked="OnNewClicked" />
</StackLayout>
</DataTemplate>
</ListView.FooterTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
?
按照上面的XAML,在应用程序执行"?OnSelection上‘‘的方法ItemSelected名单"事件,以显示详细的员工信息,"OnNewClicked?‘上‘的方法点击了?‘的‘事件添加新员工?"按钮。本页面背后的代码将包含以下代码。
using System;
using Xamarin.Forms;
?
namespace SQLiteEx
{
public partial class ManageEmployee : ContentPage
{
public ManageEmployee()
{
InitializeComponent();
var vList = App.DAUtil.GetAllEmployees();
lstData.ItemsSource = vList;
}
?
void OnSelection(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
//ItemSelected is called on deselection,
//which results in SelectedItem being set to null
}
var vSelUser = (Employee)e.SelectedItem;
Navigation.PushAsync(new ShowEmplyee(vSelUser));
}
public void OnNewClicked(object sender, EventArgs args)
{
Navigation.PushAsync(new AddEmployee());
}
}
}
?
添加员工:顾名思义这个页面将用于增加新的员工,将根据点击的被称为"添加新员工"员工管理"页上的按钮。此页面的XAML代码将是这样的:
隐藏???复制代码
<?xml
version="1.0"
encoding="utf-8"
?><ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SQLiteEx.AddEmployee"
Title="Add New Employee"><ContentPage.Content>
???????????? <TableView
Intent="Settings"
BackgroundColor="White">???????????????? <TableRoot>
???????????????????? <TableSection
Title="Add New Employee">???????????????????????? <EntryCell
x:Name="txtEmpName"
Label="Employee Name"
Keyboard="Text"
/>???????????????????????? <EntryCell
x:Name="txtDesign"
Label="Designation"
Keyboard="Text"
/>???????????????????????? <EntryCell
x:Name="txtDepartment"
Label="Department"
Keyboard="Text"
/>???????????????????????? <EntryCell
x:Name="txtQualification"
Label="Qualification"
Keyboard="Text"
/>???????????????????????? <ViewCell>
???????????????????????????? <ContentPage
Padding="0,0"><ContentPage.Padding>
<OnPlatform
x:TypeArguments="Thickness"
iOS="10,0"
WinPhone="0,15,0,0"
/></ContentPage.Padding>
<ContentPage.Content>
<Button
BackgroundColor="#fd6d6d"
Text="Save"
TextColor="White"
Clicked="OnSaveClicked"
/></ContentPage.Content>
</ContentPage>
???????????????????????? </ViewCell>
???????????????????? </TableSection>
???????????????? </TableRoot>
???????????? </TableView>
</ContentPage.Content>
</ContentPage>
本页面背后的代码将包含以下代码:
隐藏???复制代码
using System;
using Xamarin.Forms;
?
namespace SQLiteEx
{
public
partial
class AddEmployee : ContentPage{
public AddEmployee()
{
InitializeComponent();
}
?
public
void OnSaveClicked(object sender, EventArgs args){
var vEmployee = new Employee()
{
EmpName = txtEmpName.Text,
Department = txtDepartment.Text,
Designation = txtDesign.Text,
Qualification = txtQualification.Text
};
App.DAUtil.SaveEmployee(vEmployee);
Navigation.PushAsync(new ManageEmployee());
}
}
}
?
显示员工详细信息:顾名思义,这个页面将用于显示雇员的完整细节,也将必须调用"编辑员工页面的选项,"删除员工"从数据库中删除员工的详细信息。此页面的XAML代码是这样的:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SQLiteEx.ShowEmplyee" Title="View Employee">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
?
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
?
<Label Grid.Row ="0" Grid.Column="0" Grid.ColumnSpan="2" Text="Employee Details" />
<Label Grid.Row ="1" Grid.Column="1" Text="Name" />
<Label Grid.Row="1" Grid.Column="2" Text ="{Binding EmpName}" />
<Label Grid.Row ="2" Grid.Column="1" Text="Designation" />
<Label Grid.Row="2" Grid.Column="2" Text ="{Binding Designation}"/>
<Label Grid.Row ="3" Grid.Column="1" Text="Department" />
<Label Grid.Row="3" Grid.Column="2" Text ="{Binding Department}"/>
<Label Grid.Row ="4" Grid.Column="1" Text="Qualification" />
<Label Grid.Row="4" Grid.Column="2" Text ="{Binding Qualification}" />
<Button Grid.Row ="5" Grid.Column="1" Text="Edit Details" Clicked="OnEditClicked" />
<Button Grid.Row="5" Grid.Column="2" Text="Delete" Clicked="OnDeleteClicked" />
</Grid>
</ContentPage.Content>
</ContentPage>
而这个页面背后的代码将包含以下代码:
using System;
using Xamarin.Forms;
?
namespace SQLiteEx
{
public partial class ShowEmplyee : ContentPage
{
Employee mSelEmployee;
public ShowEmplyee(Employee aSelectedEmp)
{
InitializeComponent();
mSelEmployee = aSelectedEmp;
BindingContext = mSelEmployee;
}
?
public void OnEditClicked(object sender, EventArgs args)
{
Navigation.PushAsync(new EditEmployee(mSelEmployee));
}
public async void OnDeleteClicked(object sender, EventArgs args)
{
bool accepted = await DisplayAlert("Confirm", "Are you Sure ?", "Yes", "No");
if (accepted)
{
App.DAUtil.DeleteEmployee(mSelEmployee);
}
await Navigation.PushAsync(new ManageEmployee());
}
}
}
?
编辑员工:顾名思义,这个页面将用于编辑员工的详细信息。此页面的XAML代码是这样的:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SQLiteEx.EditEmployee" Title="Edit Employee">
<ContentPage.Content>
<TableView Intent="Settings" BackgroundColor="White">
<TableRoot>
<TableSection Title="Edit Employee">
<EntryCell x:Name="txtEmpName" Label="Employee Name" Text ="{Binding EmpName}" Keyboard="Text" />
<EntryCell x:Name="txtDesign" Label="Designation" Text ="{Binding Designation}" Keyboard="Text" />
<EntryCell x:Name="txtDepartment" Label="Department" Text ="{Binding Department}" Keyboard="Text" />
<EntryCell x:Name="txtQualification" Label="Qualification" Text ="{Binding Qualification}" Keyboard="Text" />
<ViewCell>
<ContentPage Padding="0,0">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="10,0" WinPhone="0,15,0,0" />
</ContentPage.Padding>
<ContentPage.Content>
<Button BackgroundColor="#fd6d6d" Text="Save" TextColor="White" Clicked="OnSaveClicked" />
</ContentPage.Content>
</ContentPage>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
</ContentPage.Content>
</ContentPage>
而这个页面背后的代码将包含以下代码:
而这个页面背后的代码将包含以下代码:
隐藏???复制代码
using System;
using Xamarin.Forms;
?
namespace SQLiteEx
{
public
partial
class EditEmployee : ContentPage{
Employee mSelEmployee;
public EditEmployee(Employee aSelectedEmp)
{
InitializeComponent();
mSelEmployee = aSelectedEmp;
BindingContext = mSelEmployee;
}
?
public
void OnSaveClicked(object sender, EventArgs args){
mSelEmployee.EmpName = txtEmpName.Text;
mSelEmployee.Department = txtDepartment.Text;
mSelEmployee.Designation = txtDesign.Text;
mSelEmployee.Qualification = txtQualification.Text;
App.DAUtil.EditEmployee(mSelEmployee);
Navigation.PushAsync(new ManageEmployee());
}
}