Xamarin.Forms’da SQLite Kullanımı | DependencyService
İçindekiler
Bu yazımda Xamarin.Forms ile daha önceden geliştirdiğim Hava Durumu uygulamasına SQLite ile yerel veritabanı ekleyeceğim.
1) Xamarin.Forms projenize SQLite eklentisini yükleyin
Öncelikle, Xamarin.Forms projenizde SQLite ile bir veritabanı oluşturabilmek için sqlite-net-pcl eklentisini yüklemelisiniz.
Paket Yöneticisi Konsolunda aşağıdaki kodu çalıştırarak eklentiyi yükleyebilirsiniz. (bkz. Paket Yöneticisi Konsolu ile NuGet Paketlerini Yükleme)
Install-Package sqlite-net-pcl -Version 1.8.0-beta
Alternatif olarak, eklentiyi NuGet Paket Yöneticisinden de yükleyebilirsiniz. (bkz. NuGet Paket Yöneticisi İle NuGet Paketlerini Yükleme)

2) IDatabase interface’si ekleyin
MVVM modelinde Data klasöründe, veritabanı işlemlerinin yapılacağı sınıflar ve interface’ler yer alır.
Projeye Data adlı bir klasör ekleyin ve bu klasöre IDatabase.cs adlı bir interface ekleyin.
IDatabase interface’sinde GetConnection() adında bir method tanımlayın. Android yerel platformunda bir veritabanı bağlantısı oluştururken bu methodu override edeceksiniz. Yani Android platformunun özelliklerini DependencyService ile Xamarin.Forms’da kullanacaksınız.
public interface IDatabase
{
SQLiteConnection GetConnection();
}
3) SQLite Dependecy Service ekleyin
Şimdi projenizin Android klasörüne Connection adlı bir klasör ekleyin. Ardından Connection klasörüne SQLiteConnection.cs adlı bir sınıf ekleyin.
SQLiteConnection.cs sınıfı IDatabase interface’sini implement eder ve dolayısıyla GetConnection() methodunu override etmek zorundadır. GetConnection() methodu içerisinde Places.db adında bir veritabanı oluşturun ve SQLite bağlantısı kurun.
[assembly: Dependency(typeof(Weather.Droid.Connection.SQLiteConnection))]
namespace Weather.Droid.Connection
{
class SQLiteConnection : IDatabase
{
public SQLite.SQLiteConnection GetConnection()
{
var filename = "Places.db";
var documentspath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var path = Path.Combine(documentspath, filename);
var connection = new SQLite.SQLiteConnection(path);
return connection;
}
}
}
Ayrıca bu sınıfın bir Dependency olduğunu bildirmeyi unutmayın.
[assembly: Dependency(typeof(Weather.Droid.Connection.SQLiteConnection))]
4) Model sınıfı ekleyin
Models klasörüne Places.cs adlı bir sınıf ekleyin. Bu sınıf, Id, CityName, Latitude, Longitude ve City Key özelliklerini içerir. Places sınıfı, ekleyeceğiniz her bir yerin bilgilerini içeren model sınıfıdır. Yani ileride veritabanına ekleyeceğiniz her bir yer bu modele uygun olmalıdır.
Id property’sindeki [PrimaryKey, AutoIncrement] ise Id’nin birincil anahar ve otomatik artan bir değer olduğunu gösterir.
public class Places
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string CityName { get; set; }
public double CityLat { get; set; }
public double CityLon { get; set; }
public string CityKey { get; set; }
}
}
5) Database sınıfı ekleyin
Projeye Datas adında bir klasör ekleyin ve bu klasöre Database.cs adlı bir sınıf ekleyin.
Bu sınıf içerisinde, öncelikle Android platformunda oluşturduğunuz GetConnection() methodunu çağırarak veritabanı ile bağlantı kurun. Ardından veritabanında “Places” adlı bir tablo oluşturun. Daha sonra Places tablosunda CRUD ve diğer veritabanı işlemlerini uygulayın.
public class Database
{
static object locker = new object();
SQLiteConnection _sqlconnection;
public Database()
{
_sqlconnection = DependencyService.Get<IDatabase>().GetConnection();
_sqlconnection.CreateTable<Places>();
}
public int Insert(Places place)
{
lock (locker)
{
return _sqlconnection.Insert(place);
}
}
public int Update(Places place)
{
lock (locker)
{
return _sqlconnection.Update(place);
}
}
public int Delete(int id)
{
lock (locker)
{
return _sqlconnection.Delete<Places>(id);
}
}
public IEnumerable<Places> GetAll()
{
lock (locker)
{
return (from i in _sqlconnection.Table<Places>() select i).ToList();
}
}
public int FullDelete()
{
lock (locker)
{
return _sqlconnection.DeleteAll<Places>();
}
}
public Places Get(int id)
{
lock (locker)
{
return _sqlconnection.Table<Places>().FirstOrDefault(t => t.Id == id);
}
}
public List<Places> GetFirst()
{
lock (locker)
{
return _sqlconnection.Query<Places>("SELECT * FROM Places LIMIT 1");
}
}
public void Dispose()
{
_sqlconnection.Dispose();
}
}
6) ViewModel sınıflarını ekleyin
Projeye SQLite eklerken iki tane Viewmodel sınıfına ihtiyacınız var.
- İlki, veritabanında kayıtlı olan yerleri listeleyecek olan PlacesPage.xaml sayfasının PlacesViewModel.cs sınıfı.
- İkincisi, yeni bir konum ekleyeceğiniz AddPlacesPage.xaml sayfasının AddPlacesViewModel.cs sınıfı.
PlacesViewModel.cs
PlacesViewModel sınıfında, ilk olarak GetConnection() yöntemi SQLite veritabanı bağlantısı oluşturur. Daha sonra kurucu methodunda Databse sınıfının GetAll() methodu çağırılır ve kaydedilen tüm verileri döndürür.
public class PlacesViewModel : INotifyPropertyChanged
{
private static Database database = null;
private static Database GetConnection()
{
if (database == null)
database = new Database();
return database;
}
public event PropertyChangedEventHandler PropertyChanged;
private IEnumerable<Places> _places;
public IEnumerable<Places> Places
{
get
{
return _places;
}
set
{
_places = value;
OnPropertyChanged();
}
}
public PlacesViewModel()
{
Places = GetConnection().GetAll();
}
public ICommand BackCommand => new Command(Back);
private async void Back()
{
await App.Current.MainPage.Navigation.PopModalAsync();
}
public ICommand TapCommand => new Command(Tap);
private async void Tap()
{
await App.Current.MainPage.Navigation.PushModalAsync(new AddPlacesPage());
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
AddPlacesViewModel.cs
AddPlacesViewModel sınıfı AddPlacesPage.xaml sayfasına bağlanacak olan sınıftır. Yani AddPlaces.xaml sayfasına girdiğiniz bilgileri SQLite veritabanına kaydedecek olan sınıf.
AddPlacesViewModel sınıfına gerekli propertyleri ve komutları aşağıdaki gibi ekleyin.
public class AddPlacesViewModel : INotifyPropertyChanged
{
private string _cityName;
public string CityName
{
get { return _cityName; }
set
{
_cityName = value;
OnPropertyChanged();
}
}
private string _cityKey;
public string CityKey
{
get { return _cityKey; }
set
{
_cityKey = value;
OnPropertyChanged();
}
}
private double _cityLat;
public double CityLat
{
get { return _cityLat; }
set
{
_cityLat = value;
OnPropertyChanged();
}
}
private double _cityLon;
public double CityLon
{
get { return _cityLon; }
set
{
_cityLon = value;
OnPropertyChanged();
}
}
private Places places = new Places();
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
public AddPlacesViewModel()
{
}
public ICommand TapCommand => new Command(Tap);
private async void Tap()
{
Database database = new Database();
places.CityKey = CityKey;
places.CityName = CityName;
places.CityLat = CityLat;
places.CityLon = CityLon;
database.Insert(places);
await App.Current.MainPage.Navigation.PushModalAsync(new PlacesPage());
}
public ICommand BackCommand => new Command(Back);
private async void Back()
{
await App.Current.MainPage.Navigation.PopModalAsync();
}
}
7) XAML sayfalarını ekleyin
Projenizdeki Views klasörüne PlacesPage.xaml ve AddPlaces.xaml adlı iki adet ContentPage ekleyin. Adından da anlaşılacağı gibi, konum ekleyeceğiniz ve konumları görüntüleyeceğiniz sayfalar bunlar olacak.
PlacesPage.xaml
1 Projenizin Views klasörüne PlacesPage.xaml adlı bir ContentPage ekleyin. Bu XAML sayfası veritabanında kayıtlı olan yerleri gösterecek.
2 Ardından PlacesPage.xaml.cs sınıfına gidin ve bu sınıfın yapıcı yöntemine BindingContext nesnesi ile PlacesViewModel sınıfını bağlayın. (Xamarin.Forms’da Temel Veri Bağlama Kavramı)
public partial class PlacesPage : ContentPage
{
public PlacesPage()
{
InitializeComponent();
BindingContext = new PlacesViewModel();
}
}
3 Şimdi PlacesPage.xaml sayfasını açın. Bu XAML sayfasına bir CollectionView ekleyin ve PlacesViewModel sınıfındaki Places IEnumarable’sini bağlayın. Böylece veritabanındaki veriler CollectionView içerisinde görüntülenecek.
Daha sonra bir PancakeView içerisinde sağ alt köşeye bir Flyout button ekleyin.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pancakeview="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
mc:Ignorable="d"
x:Class="Weather.View.PlacesPage"
BackgroundColor="#F5F8FD">
<AbsoluteLayout >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" HorizontalOptions="Center" VerticalOptions="Center" Margin="20,10,20,10" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<pancakeview:PancakeView Grid.Column="0" WidthRequest="41" HeightRequest="41" CornerRadius="10" BackgroundColor="#FFF">
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000"/>
</pancakeview:PancakeView.Shadow>
<pancakeview:PancakeView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BackCommand}"/>
</pancakeview:PancakeView.GestureRecognizers>
<Image Source="back.png" HorizontalOptions="Center" VerticalOptions="Center" Margin="10" />
</pancakeview:PancakeView>
<Label Grid.Column="2" Text="Locations" VerticalOptions="Center" HorizontalOptions="Center" FontSize="25" FontAttributes="Bold" TextColor="#7B7C7D"/>
<pancakeview:PancakeView Grid.Column="4" WidthRequest="41" HeightRequest="41" CornerRadius="10" BackgroundColor="#FFF">
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000" />
</pancakeview:PancakeView.Shadow>
<Image Source="menu.png" HorizontalOptions="Center" VerticalOptions="Center" Margin="10" />
</pancakeview:PancakeView>
</Grid>
</StackLayout>
<CollectionView Grid.Row="1" SelectionMode="Single" ItemsSource="{Binding Places}" SelectedItem="{Binding SelectedPlaces}" SelectionChangedCommand="{Binding SelectionCommand}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate >
<StackLayout>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" >
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#b9ceeb" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<pancakeview:PancakeView BackgroundColor="#87a8d0" HeightRequest="120" WidthRequest="350" CornerRadius="20" HorizontalOptions="Center" VerticalOptions="Center" Margin="20,10,20,10">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Text="{Binding CityName}" TextColor="White" FontSize="41" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" Margin="10,0,0,0" />
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding CityKey, StringFormat='City Key: {0:N0}'}" TextColor="White" FontSize="15" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" Margin="15,-10,0,0" />
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding CityLat, StringFormat='Latitude: {0:N0}'}" TextColor="White" FontSize="15" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" Margin="15,-10,0,0" />
<Label Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding CityLon, StringFormat='Longitude: {0:N0}'}" TextColor="White" FontSize="15" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" Margin="15,-10,0,0" />
</Grid>
</pancakeview:PancakeView>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
<pancakeview:PancakeView AbsoluteLayout.LayoutBounds="0.90,0.95,60,60"
AbsoluteLayout.LayoutFlags="PositionProportional" BackgroundColor="#fff" HeightRequest="60" WidthRequest="60" CornerRadius="60" BackgroundGradientStartPoint="0,0" BackgroundGradientEndPoint="1,0">
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000000" Offset="10,10" />
</pancakeview:PancakeView.Shadow>
<pancakeview:PancakeView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding TapCommand}" NumberOfTapsRequired="2"/>
</pancakeview:PancakeView.GestureRecognizers>
<Image Source="add.png" HeightRequest="33" WidthRequest="33" HorizontalOptions="Center" VerticalOptions="Center"/>
</pancakeview:PancakeView>
</AbsoluteLayout>
</ContentPage>
AddPlacesPage.xaml
1 Projenizin Views klasörüne AddPlacesPage.xaml adında bir ContentPage ekleyin. Bu sayfada oluşturacağınız form ile veritabanına yeni yerler ekleyeceksiniz.
2 Ardından AddPlacesPage.xaml.cs sınıfına gidin ve bu sınıfın yapıcı yöntemine BindingContext nesnesi ile AddPlacesViewModel sınıfını bağlayın. (Xamarin.Forms’da Temel Veri Bağlama Kavramı)
public partial class AddPlacesPage : ContentPage
{
public AddPlacesPage()
{
InitializeComponent();
BindingContext = new AddPlacesViewModel();
}
}
3 Şimdi AddPlacesPage.xaml sayfasını açın. Bu XAML sayfasında yeni yerler eklemek için kullanacağınız bir form oluşturun.
Burada ben yine PancakeView ile görünümde özelleştirmeler yaptım.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pancakeview="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
mc:Ignorable="d"
x:Class="Weather.View.AddPlacesPage">
<StackLayout >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" HorizontalOptions="Center" VerticalOptions="Center" Margin="20,10,20,10" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<pancakeview:PancakeView Grid.Column="0" WidthRequest="41" HeightRequest="41" CornerRadius="10" BackgroundColor="#FFF">
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000"/>
</pancakeview:PancakeView.Shadow>
<pancakeview:PancakeView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BackCommand}"/>
</pancakeview:PancakeView.GestureRecognizers>
<Image Source="back.png" HorizontalOptions="Center" VerticalOptions="Center" Margin="10" />
</pancakeview:PancakeView>
<pancakeview:PancakeView Grid.Column="3" WidthRequest="41" HeightRequest="41" CornerRadius="10" BackgroundColor="#FFF">
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000" />
</pancakeview:PancakeView.Shadow>
<Image Source="menu.png" HorizontalOptions="Center" VerticalOptions="Center" Margin="10" />
</pancakeview:PancakeView>
</Grid>
</StackLayout>
<StackLayout Grid.Row="1" HorizontalOptions="Center" VerticalOptions="Center" Margin="20,10,20,10" >
<pancakeview:PancakeView BackgroundColor="#deecfc" HeightRequest="50" WidthRequest="350" CornerRadius="5" HorizontalOptions="Center" VerticalOptions="Center" BackgroundGradientStartPoint="0,0" BackgroundGradientEndPoint="1,0">
<Entry x:Name="cityName" Placeholder="CityName" HorizontalOptions="FillAndExpand" Text="{Binding CityName}"></Entry>
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000000" Offset="10,10" />
</pancakeview:PancakeView.Shadow>
</pancakeview:PancakeView>
<pancakeview:PancakeView BackgroundColor="#deecfc" HeightRequest="50" WidthRequest="350" CornerRadius="5" HorizontalOptions="Center" VerticalOptions="Center" BackgroundGradientStartPoint="0,0" BackgroundGradientEndPoint="1,0">
<Entry x:Name="cityKey" Placeholder="CityKey" HorizontalOptions="FillAndExpand" Text="{Binding CityKey}"></Entry>
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000000" Offset="10,10" />
</pancakeview:PancakeView.Shadow>
</pancakeview:PancakeView>
<pancakeview:PancakeView BackgroundColor="#deecfc" HeightRequest="50" WidthRequest="350" CornerRadius="5" HorizontalOptions="Center" VerticalOptions="Center" BackgroundGradientStartPoint="0,0" BackgroundGradientEndPoint="1,0">
<Entry x:Name="cityLat" Placeholder="CityLat" HorizontalOptions="FillAndExpand" Text="{Binding CityLat}"></Entry>
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000000" Offset="10,10" />
</pancakeview:PancakeView.Shadow>
</pancakeview:PancakeView>
<pancakeview:PancakeView BackgroundColor="#deecfc" HeightRequest="50" WidthRequest="350" CornerRadius="5" HorizontalOptions="Center" VerticalOptions="Center" BackgroundGradientStartPoint="0,0" BackgroundGradientEndPoint="1,0">
<Entry x:Name="cityLon" Placeholder="CityLon" HorizontalOptions="FillAndExpand" Text="{Binding CityLon}"></Entry>
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#000000" Offset="10,10" />
</pancakeview:PancakeView.Shadow>
</pancakeview:PancakeView>
<pancakeview:PancakeView BackgroundColor="#87a8d0" HeightRequest="50" WidthRequest="350" CornerRadius="10" HorizontalOptions="Center" VerticalOptions="Center" BackgroundGradientStartPoint="0,0" BackgroundGradientEndPoint="1,0">
<Label Text="SAVE" FontSize="Large" FontAttributes="Bold" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<pancakeview:PancakeView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding TapCommand}"/>
</pancakeview:PancakeView.GestureRecognizers>
<pancakeview:PancakeView.BackgroundGradientStops>
<pancakeview:GradientStopCollection>
<pancakeview:GradientStop Color="#87a8d0" Offset="0" />
<pancakeview:GradientStop Color="#b9ceeb" Offset="1" />
</pancakeview:GradientStopCollection>
</pancakeview:PancakeView.BackgroundGradientStops>
<pancakeview:PancakeView.Shadow>
<pancakeview:DropShadow Color="#87a8d0" Offset="10,10" />
</pancakeview:PancakeView.Shadow>
</pancakeview:PancakeView>
</StackLayout>
</Grid>
</StackLayout>
</ContentPage>
Tüm adımları tamamladıktan sonra uygulamayı çalıştırın ve nasıl göründüğüne bakın.


