Mobile Local Databases In Xamarin.Forms Using SQLite

Introduction

The most frequent feature requirement in mobile applications is the online and offline feature. In online mode, mobile apps exchange data over networks, using cloud storage.

In offline mode, mobile apps only need to store data in mobile storage locally. With simple unstructured data, such as - user settings, options, and cloud download data, applications can store information inside local files or local database.

This article will show a step by step guide on how to use an SQLite database with a Xamarin.Forms application in iOS, Android, and Windows Universal application. I have seen most of the articles on SQLite implementation but everywhere they use Dependency and creating database in platform specific code.

The sample, shown below, is about Cross Mobile local database in Xamarin.Forms using SQLite with 100% code re-use to all the platforms.


Step 1 Create New Xamarin.Forms Application

Create new Xamarin.Form application using Visual Studio 2015 or Xamarin Studio. You can refer to my previous article for creating new Xamarin.Forms  Application



Step 2 Add SQLite NuGet Package

After creating Xamarin.Forms application, you need a managed way to access SQLite database. You need to add a reference to portable SQLite library from our project.

SQLite-net-pcl is on open source and lightweight library for .NET, Mono, and Xamarin applications. It’s available as a NuGet package with the name sqlite-net-pcl .

Right click on Solution - Manage NuGet Package for Solution - Search “Sqlite-net-pcl” - select all platform project - Click on "Install".



Step 3 Add PCLStorage Package

PCL Storage provides a consistent, portable set of local files I/O APIs for .NET, Windows Phone, Windows Store, Xamarin.iOS, Xamarin.Android, and Silverlight. This makes it easier to create cross-platform .NET libraries and apps.

Here, we need to save SQLite database to all the platforms and local storage, so for getting local storage path we are using PCLStorage .

Add PCLStorage Nuget package to all the projects. Right click on Project Solution - Click “Manage NuGet package for Solution “ - Search and select “PCLStorage” - Select all the Projects - Click Install.



Step 4 Create Entity For table

You have created one Data Model Entity with below table column.


  1. using SQLite;  
  2. namespace DevEnvExe_LocalStorage  
  3. {  
  4.     public class RegEntity  
  5.     {  
  6.         public RegEntity()  
  7.         {  
  8.         }  
  9.   
  10.         [PrimaryKey, AutoIncrement]  
  11.         public int ID { get; set; }  
  12.         public string Name { get; set; }  
  13.         public string Username { get; set; }  
  14.         public string Password { get; set; }  
  15.     }  
  16. }  
Step 4 Create SQLHelper Class

Create "New class" and add method for SQL connection and Get, Update, Insert,  and Delete data.

Right Click Portable Class Library - Add New Item - select Class and name it as “SQLHelper”.

Using directives

You need to add the following using reference from SQLHelper class and what you need in this class are two fields that store the connection string and an object that will be used to implement locks on data operations, to avoid database collisions.
  1. using SQLite;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using PCLStorage;  
  5.   
  6. namespace DevEnvExe_LocalStorage  
  7. {  
  8.     public class SqlHelper  
  9.     {  
  10.         static object locker = new object();  
  11.         SQLiteConnection database;  
SQLite Connection

Sqlite Connection Common for all the platforms. The below code will be used for getting  local storage path and creating the Sqlite connection .
  1. public SQLite.SQLiteConnection GetConnection()  
  2.         {  
  3.             SQLiteConnection sqlitConnection;  
  4.             var sqliteFilename = "Employee.db3";  
  5.             IFolder folder = FileSystem.Current.LocalStorage;  
  6.             string path = PortablePath.Combine(folder.Path.ToString(), sqliteFilename);  
  7.             sqlitConnection = new SQLite.SQLiteConnection(path);   
  8.             return sqlitConnection;  
  9.         }  
Create Table

Now it’s time to implement the class constructor; the above method will return DBConnection using that creates table in the Sqlite Database
  1. public SqlHelper()  
  2.         {  
  3.             database = GetConnection();  
  4.             // create the tables  
  5.             database.CreateTable<RegEntity>();  
  6.         }  
Get Data

The below code is to get  all the registered user's details.
  1. public IEnumerable<RegEntity> GetItems()  
  2.         {  
  3.             lock (locker)  
  4.             {  
  5.                 return (from i in database.Table<RegEntity>() select i).ToList();  
  6.             }  
  7.         }  
The  below code is get the all the user details and filter by user parameter .
  1. public RegEntity GetItem(string userName)  
  2.       {  
  3.           lock (locker)  
  4.           {  
  5.               return database.Table<RegEntity>().FirstOrDefault(x => x.Username == userName);  
  6.           }  
  7.       }  
Insert and Update Data

The SaveItem method will act as insert and update. if its ID value is 0 it means it will insert the value to sqlite otherwise it will be updated on an item based ID .
  1. public int SaveItem(RegEntity item)  
  2.         {  
  3.             lock (locker)  
  4.             {  
  5.                 if (item.ID != 0)  
  6.                 {  
  7.                     //Update Item  
  8.                     database.Update(item);  
  9.                     return item.ID;  
  10.                 }  
  11.                 else  
  12.                 {  
  13.                     //Insert item  
  14.                     return database.Insert(item);  
  15.                 }  
  16.             }  
  17.         }  
Delete Data

The below code deletes the item based on ID
  1. public int DeleteItem(int id)  
  2.         {  
  3.             lock (locker)  
  4.             {  
  5.                 return database.Delete<RegEntity>(id);  
  6.             }  
  7.         }  
SQLHelper Class

I have included all the helper methods for your reference
  1. using SQLite;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using PCLStorage;  
  5.   
  6. namespace DevEnvExe_LocalStorage  
  7. {  
  8.     public class SqlHelper  
  9.     {  
  10.         static object locker = new object();  
  11.         SQLiteConnection database;  
  12.         public SqlHelper()  
  13.         {  
  14.             database = GetConnection();  
  15.             // create the tables  
  16.             database.CreateTable<RegEntity>();  
  17.         }  
  18.         public SQLite.SQLiteConnection GetConnection()  
  19.         {  
  20.             SQLiteConnection sqlitConnection;  
  21.             var sqliteFilename = "Employee.db3";  
  22.             IFolder folder = FileSystem.Current.LocalStorage;  
  23.             string path = PortablePath.Combine(folder.Path.ToString(), sqliteFilename);  
  24.             sqlitConnection = new SQLite.SQLiteConnection(path);   
  25.             return sqlitConnection;  
  26.         }  
  27.   
  28.         public IEnumerable<RegEntity> GetItems()  
  29.         {  
  30.             lock (locker)  
  31.             {  
  32.                 return (from i in database.Table<RegEntity>() select i).ToList();  
  33.             }  
  34.         }  
  35.   
  36.         public RegEntity GetItem(string userName)  
  37.         {  
  38.             lock (locker)  
  39.             {  
  40.                 return database.Table<RegEntity>().FirstOrDefault(x => x.Username == userName);  
  41.             }  
  42.         }  
  43.         public RegEntity GetItem(string userName ,string passWord)  
  44.         {  
  45.             lock (locker)  
  46.             {  
  47.                 return database.Table<RegEntity>().FirstOrDefault(x => x.Username == userName && x.Password ==passWord);  
  48.             }  
  49.         }  
  50.         public int SaveItem(RegEntity item)  
  51.         {  
  52.             lock (locker)  
  53.             {  
  54.                 if (item.ID != 0)  
  55.                 {  
  56.                     //Update Item  
  57.                     database.Update(item);  
  58.                     return item.ID;  
  59.                 }  
  60.                 else  
  61.                 {  
  62.                     //Insert item  
  63.                     return database.Insert(item);  
  64.                 }  
  65.             }  
  66.         }  
  67.   
  68.         public int DeleteItem(int id)  
  69.         {  
  70.             lock (locker)  
  71.             {  
  72.                 return database.Delete<RegEntity>(id);  
  73.             }  
  74.         }  
  75.     }  
  76. }  
Step 4 UI Design

Login page

You can create Login Page as per the below design with two entry boxes and buttons



Xaml Design

You can reference the  below xaml code and add it in your login page
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.              xmlns:local="clr-namespace:DevEnvExe_LocalStorage"  
  5.              x:Class="DevEnvExe_LocalStorage.MainPage"  
  6.      Padding="0, 20, 0, 0">  
  7.   
  8.   <Grid>  
  9.     <Grid.RowDefinitions>  
  10.       <RowDefinition Height="Auto" />  
  11.       <RowDefinition Height="Auto" />  
  12.       <RowDefinition Height="Auto" />  
  13.       <RowDefinition Height="Auto" />  
  14.     </Grid.RowDefinitions>  
  15.   
  16.     <Grid.ColumnDefinitions>  
  17.       <ColumnDefinition Width="Auto" />  
  18.       <ColumnDefinition Width="Auto" />  
  19.       <ColumnDefinition Width="300" />  
  20.     </Grid.ColumnDefinitions>  
  21.     <Label Text="Login" Grid.Row="0" Grid.Column="2" FontSize="50" ></Label>  
  22.   
  23.     <Entry Placeholder="UserID" x:Name="txtuserid" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"  ></Entry>  
  24.   
  25.     <Entry IsPassword="True" x:Name="txtpassword" Placeholder="Password" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" ></Entry>  
  26.     <StackLayout Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3">  
  27.       <Button Text="Login" Clicked="Click_Login" ></Button>  
  28.       <Button Text="Registrtion" Clicked="Click_Reg" ></Button>  
  29.     </StackLayout>  
  30.   
  31.   </Grid>  
  32.   
  33. </ContentPage>  
C# Code

The below code is Login check to see if userid and password already available or not. If it’s not available navigate to Register page otherwise  navigate to Edit profile page (Home Page)
  1. RegEntity userDetail = App.Database.GetItem(txtuserid.Text, txtpassword.Text);  
Above Get method will return user details.
  1. using System;  
  2. using Xamarin.Forms;  
  3.   
  4. namespace DevEnvExe_LocalStorage  
  5. {  
  6.     public partial class MainPage : ContentPage  
  7.     {  
  8.         public MainPage()  
  9.         {  
  10.             InitializeComponent();  
  11.         }  
  12.         async void Click_Reg(object sender, EventArgs e)  
  13.         {  
  14.             await Navigation.PushModalAsync(new Registration());  
  15.         }  
  16.   
  17.         async void Click_Login(object sender, EventArgs e)  
  18.         {  
  19.             RegEntity userDetail = App.Database.GetItem(txtuserid.Text, txtpassword.Text);  
  20.   
  21.             if (userDetail != null)  
  22.             {  
  23.                 if (txtuserid.Text != userDetail.Username && txtpassword.Text != userDetail.Password)  
  24.                 {  
  25.                     await DisplayAlert("Login""Login failed .. Please try again ""OK");  
  26.                 }  
  27.                 else  
  28.                 {  
  29.                     await DisplayAlert("Registrtion""Login Success ... Now Edit your profile ""OK");  
  30.                     await Navigation.PushModalAsync(new Home(txtuserid.Text));  
  31.                 }  
  32.             }  
  33.             else  
  34.             {  
  35.                 await DisplayAlert("Login""Login failed .. Please try again ""OK");  
  36.             }  
  37.   
  38.   
  39.         }  
  40.   
  41.     }  
  42. }  
Registration page

You can create Registration Page as per the below design with 3 entry boxes and buttons



Xaml Design

You can refer to the below xaml code for registration page design
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.              x:Class="DevEnvExe_LocalStorage.Registration"  
  5.              Padding="0, 20, 0, 0">  
  6.   
  7.   <Grid>  
  8.     <Grid.RowDefinitions>  
  9.       <RowDefinition Height="Auto" />  
  10.       <RowDefinition Height="Auto" />  
  11.       <RowDefinition Height="Auto" />  
  12.       <RowDefinition Height="Auto" />  
  13.       <RowDefinition Height="Auto" />  
  14.     </Grid.RowDefinitions>  
  15.   
  16.     <Grid.ColumnDefinitions>  
  17.       <ColumnDefinition Width="Auto" />  
  18.       <ColumnDefinition Width="Auto" />  
  19.       <ColumnDefinition Width="300" />  
  20.     </Grid.ColumnDefinitions>  
  21.     <Label Text="Registartion" Grid.Row="0" Grid.Column="2" FontSize="50" ></Label>  
  22.   
  23.     <Entry Placeholder="Name" x:Name="txtname" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"  ></Entry>  
  24.     <Entry Placeholder="UserID"  x:Name="txtuserid" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"  ></Entry>  
  25.   
  26.     <Entry IsPassword="True"  x:Name="txtpassword" Placeholder="Password" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" ></Entry>  
  27.     <StackLayout Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3">  
  28.       <Button Text="Registrtion" Clicked="Click_Reg" ></Button>  
  29.       <Button Text="Already Register ... Login " Clicked="Click_Login"></Button>  
  30.     </StackLayout>  
  31.   
  32.   </Grid>  
  33.   
  34. </ContentPage>  
C# Code

The below method will save the user details into SQLite database.
  1. RegEntity OReg = new RegEntity();  
  2. OReg.Name = txtname.Text;  
  3. OReg.Username = txtuserid.Text;  
  4. OReg.Password = txtpassword.Text;  
  5. int i = App.Database.SaveItem(OReg);  
Here, save method will save the user details while sending parameter ID; value is by default 0
  1. using System;  
  2.   
  3. using Xamarin.Forms;  
  4.   
  5. namespace DevEnvExe_LocalStorage  
  6. {  
  7.     public partial class Registration : ContentPage  
  8.     {  
  9.         public Registration()  
  10.         {  
  11.             InitializeComponent();  
  12.         }  
  13.         async void Click_Reg(object sender, EventArgs e)  
  14.         {  
  15.            
  16.           if (txtuserid.Text != "")  
  17.             {  
  18.                 RegEntity fileexist = App.Database.GetItem(txtuserid.Text);  
  19.                 if (fileexist == null)  
  20.                 {  
  21.                     if (txtname.Text != "" && txtpassword.Text != "" && txtuserid.Text != "")  
  22.                     {  
  23.                         RegEntity OReg = new RegEntity();  
  24.                         OReg.Name = txtname.Text;  
  25.                         OReg.Username = txtuserid.Text;  
  26.                         OReg.Password = txtpassword.Text;  
  27.                         int i = App.Database.SaveItem(OReg);  
  28.                         if (i > 0)  
  29.                         {  
  30.                             await DisplayAlert("Registrtion""Registrtion Success ... Login and Edit profile ""OK");  
  31.                             await Navigation.PushModalAsync(new MainPage());  
  32.                         }  
  33.                         else  
  34.                         {  
  35.                             await DisplayAlert("Registrtion""Registrtion Fail .. Please try again ""OK");  
  36.                         }  
  37.                     }  
  38.                 }  
  39.                 else  
  40.                 {  
  41.                     await DisplayAlert("Registrtion Failed""username already exist .. Please try differnt user name ""OK");  
  42.                     txtuserid.Text = "";  
  43.                     txtuserid.Focus();  
  44.   
  45.                 }  
  46.             }  
  47.   
  48.         }  
  49.         async void Click_Login(object sender, EventArgs e)  
  50.         {  
  51.             await Navigation.PushModalAsync(new MainPage());  
  52.         }  
  53.     }  
  54. }  
Home page

You can create edit profile page like below



Xaml Design

You can refer to the  below code for creating updated profile page
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
  4.              x:Class="DevEnvExe_LocalStorage.Home">  
  5.  <Grid>  
  6.     <Grid.RowDefinitions>  
  7.       <RowDefinition Height="Auto" />  
  8.       <RowDefinition Height="Auto" />  
  9.       <RowDefinition Height="Auto" />  
  10.       <RowDefinition Height="Auto" />  
  11.       <RowDefinition Height="Auto" />  
  12.     </Grid.RowDefinitions>  
  13.   
  14.     <Grid.ColumnDefinitions>  
  15.       <ColumnDefinition Width="Auto" />  
  16.       <ColumnDefinition Width="Auto" />  
  17.       <ColumnDefinition Width="300" />  
  18.     </Grid.ColumnDefinitions>  
  19.     <Label Text="Registartion" Grid.Row="0" Grid.Column="2" FontSize="50" ></Label>  
  20.   
  21.     <Entry Placeholder="Name" x:Name="txtname" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"  ></Entry>  
  22.     <Entry Placeholder="UserID"  x:Name="txtuserid" IsEnabled="false" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"  ></Entry>  
  23.   
  24.     <Entry IsPassword="True"  x:Name="txtpassword" Placeholder="Password" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" ></Entry>  
  25.     <StackLayout Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3">  
  26.       <Button Text="Update Profile" Clicked="Click_UpdateProfile" ></Button>  
  27.       <Button Text="LogOut" Clicked="Click_Login"></Button>  
  28.     </StackLayout>  
  29.   
  30.   </Grid>  
  31. </ContentPage>  
C# Code

The below code gets and updates user details in sqlite database
  1. using System;  
  2.   
  3. using Xamarin.Forms;  
  4.   
  5. namespace DevEnvExe_LocalStorage  
  6. {  
  7.     public partial class Home : ContentPage  
  8.     {  
  9.         public Home(string userId)  
  10.         {  
  11.             InitializeComponent();  
  12.             GetUserDetail(userId);  
  13.   
  14.   
  15.         }  
  16.         RegEntity userDetail;  
  17.         public void GetUserDetail(string userId)  
  18.         {  
  19.             userDetail = App.Database.GetItem(userId);  
  20.             txtname.Text = userDetail.Name;  
  21.             txtuserid.Text = userDetail.Username;  
  22.             txtpassword.Text = userDetail.Password;  
  23.         }  
  24.         async void Click_UpdateProfile(object sender, EventArgs e)  
  25.         {  
  26.             int i = -1;  
  27.             if (txtname.Text != "" && txtpassword.Text != "" && txtuserid.Text != "")  
  28.             {  
  29.                 userDetail.Name = txtname.Text;  
  30.                 userDetail.Username = txtuserid.Text;  
  31.                 userDetail.Password = txtpassword.Text;  
  32.                  i = App.Database.SaveItem(userDetail);  
  33.             }  
  34.   
  35.   
  36.             if (i < 0)  
  37.             {  
  38.                 await DisplayAlert("Update Profile""Update Fail .. Please try again ""OK");  
  39.             }  
  40.             else  
  41.             {  
  42.                 await DisplayAlert("Update Profile""Profile update Success . ""OK");  
  43.             }  
  44.         }  
  45.           
  46.         async void Click_Login(object sender, EventArgs e)  
  47.         {  
  48.             await Navigation.PushModalAsync(new MainPage());  
  49.         }  
  50.     }  
  51. }  
I believe this article will help you to create local SQLite database with 100% code re-use in Xamarin.Forms . If you have any question or feedback, please share in the comment box.