Xamarin – SQLite işlemleri

21 Kas

Merhaba arkadaşlar,
Bugün ki yazımda Xamarin ile SQLite işlemleri nasıl yapılır anlatmaya çalışacağım.

Başlayalım:

– XamarinSqliteTest isimli Boş bir Android projesi açtım.

SQLite işlemlerinde kullanmak için yararlanacağımız sqlite-net-pcl isimli kütüphaneyi NuGet aracılığı ile projeye ekledim.


Model adında klasör oluşturup, altında Profile.cs adında class ekledim. Bu modeli kullanarak SQLite işlemlerimizi yapacağız.

using SQLite; eklemeyi unutmayalım

class Profile
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
        public string Email { get; set; }

        public override string ToString()
        {
            return string.Format("Profile : Id = {0}, Name = {1}, Surname = {2}, Email = {3}", Id, Name, Surname, Email);
        }
    }

– Modelimiz hazır, şimdi Profil verilerinin gösterileceği ekranını hazırlayalım; bunun için Resources > layout > klasörü altına ProfileLayout.axml isimli yeni bir Layout ekleyelim.

ProfileLayout.axml dosyamızın source kısmını açalım ve şu kodları yazarak ekranımızı şekillendirelim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="25px"
    android:minHeight="25px">
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <TableLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:stretchColumns="*">
                <TableRow>
                    <TextView
                        android:id="@+id/lblName"
                        android:text="Adı :"
                        android:layout_span="1"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
                    <TextView
                        android:id="@+id/txtName"
                        android:text=""
                        android:layout_span="2"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
                </TableRow>
                <TableRow>
                    <TextView
                        android:id="@+id/lblSurname"
                        android:text="Soyadı :"
                        android:layout_span="1"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
                    <TextView
                        android:id="@+id/txtSurname"
                        android:text=""
                        android:layout_span="2"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
                </TableRow>
                <TableRow>
                    <TextView
                        android:id="@+id/lblSurname"
                        android:text="Email :"
                        android:layout_span="1"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
                    <TextView
                        android:id="@+id/txtEmail"
                        android:text=""
                        android:layout_span="2"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
                </TableRow>
            </TableLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

Bu xml kodlarının karşılığında şöyle bir ekran oluştu;

Ekranımız artık hazır ancak bu ekranın besleneceği bir adapter classına ihtiyacımız var.
Çünkü bizim listelemek istediğimiz profile modelinde Name, Surname ve Email olmak üzere 3 adet alanımız var.
Xamarinde bir ekranda birden fazla veri listemek için adatper classlarını override etmeliyiz böylece istediğimiz Layout ekranındaki verileri doldurabiliyoruz.

Custom adapter yapma olayından önce ki yazılarımda da bahsetmiştim bu yazının sonunda faydalı linkleri görebilirsiniz. görebilirsiniz.
Biraz karmaşık gibi dursada uyguladığınızda aslında basit olduğunu göreceksiniz. Daha fazla uzatmadan devam ediyorum.

Projemize ProfileAdapter.cs isimli bir class ekleyelim.

Bu class içinde ki kodlar;

Namespaceleri kendi proje isimlerinize göre düzenlemeyi unutmayalım 🙂

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using XamarinSqliteTest.Model;

namespace XamarinSqliteTest
{
    class ProfileAdapter:BaseAdapter
    {
        private Activity context;
        private int[] id;
        private string[] name;
        private string[] surname;
        private string[] email;

        public ProfileAdapter(Activity context, List<Profile> profile)
        {
            this.context = context;
            this.id = profile.Select(x => x.Id).ToArray();
            this.name = profile.Select(x => x.Name).ToArray();
            this.surname = profile.Select(x => x.Surname).ToArray();
            this.email = profile.Select(x => x.Email).ToArray();
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            //Profile bilgilerini göstereceğimiz layotu burada belirtiyoruz.
            var view = context.LayoutInflater.Inflate(Resource.Layout.ProfileLayout, parent, false);

            // + Ekrandaki objeler çekilir, yani ProfileLayout.xaml dosyamızda ki objeler.
            TextView txtName = (TextView)view.FindViewById(Resource.Id.txtName);
            TextView txtSurname = (TextView)view.FindViewById(Resource.Id.txtSurname);
            TextView txtEmail = (TextView)view.FindViewById(Resource.Id.txtEmail);
            // -

            // + Veriler atanır.
            txtName.Text = this.name[position];
            txtSurname.Text = this.surname[position];
            txtEmail.Text = this.email[position];
            // -

            return view;
        }

        public override int Count
        {
            get
            {
                return id.Length;
            }
        }

        public override Java.Lang.Object GetItem(int position)
        {
            return null;
        }

        public override long GetItemId(int position)
        {
            return id[position];
        }
    }
}

Şuanda ProfileLayout.axml ve ProfileAdapter.cs dosyaları ile verileri listeleyeceğimiz bir kaynak dosyası yapmış olduk yani bunu şöyle düşünebilirsiniz : .Net‘te ki gridi biz burada custom olarak oluşturduk; ProfileLayout.axml dosyasını ekranda gözüken alanlar(UI) olarak, gride bağlı Datasource ise ProfileAdapter.cs dosyasıymış gibi düşünebilirsiniz.

Tıpkı bildiğimiz standart Datasource kullanımı gibi bu Datasourcu yani Adapteri nerede göstermek istiyorsak orada çekip kullanacağız.

Biz bu verileri(ProfileAdapter.cs) Main.axml ekranında listeleyeceğiz. Bunun için Main.axml dosyasına bir adet Listview ekleyelim.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="25px"
    android:minHeight="25px">
    <ListView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/mainListView" />
</LinearLayout>

– Artık profile ekranımız hazır durumda. Şimdi SQL işlemlerine geçebiliriz.
Projemizin hemen altında SQLHelper isimli klasör açalım onun altına ise ProfileHelper.cs isimli class ekleyelim;

ProfileHelper.cs;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using SQLite;
using XamarinSqliteTest.Model;
using Android.Util;

namespace XamarinSqliteTest.SQLHelper
{
    class ProfileHelper
    {
        public static string folderPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
        public static string path = System.IO.Path.Combine(folderPath, "Profile.db3");

        /// <summary>
        /// Database oluşturur.
        /// </summary>
        /// <returns></returns>
        public static bool createDatabase()
        {
            try
            {
                using (var connection = new SQLiteConnection(path))
                {
                    connection.CreateTable<XamarinSqliteTest.Model.Profile>();

                    return true;
                }
            }
            catch (SQLiteException ex)
            {
                Log.Info("SQLiteEx", ex.Message);

                return false;
            }
        }

        /// <summary>
        /// Profil tablosuna kayıt atar.
        /// </summary>
        /// <param name="profile"></param>
        /// <returns></returns>
        public static bool insert(XamarinSqliteTest.Model.Profile profile)
        {
            try
            {
                using (var connection = new SQLiteConnection(path))
                {
                    connection.Insert(profile);

                    return true;
                }
            }
            catch (SQLiteException ex)
            {
                Log.Info("SQLiteEx", ex.Message);

                return false;
            }
        }

        /// <summary>
        /// Profil tablosunu siler.
        /// </summary>
        /// <param name="profile"></param>
        /// <returns></returns>
        public static bool deleteTable()
        {
            try
            {
                using (var connection = new SQLiteConnection(path))
                {
                    connection.DeleteAll<Profile>();

                    return true;
                }
            }
            catch (SQLiteException ex)
            {
                Log.Info("SQLiteEx", ex.Message);

                return false;
            }
        }

        /// <summary>
        /// İlgili kayıdı siler.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static bool deleteRecord(int id)
        {
            try
            {
                using (var connection = new SQLiteConnection(path))
                {
                    connection.Delete<Profile>(id);

                    return true;
                }
            }
            catch (SQLiteException ex)
            {
                Log.Info("SQLiteEx", ex.Message);

                return false;
            }
        }

        /// <summary>
        /// Aranılan kaydı bulur.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Profile find(int id)
        {
            try
            {
                using (var connection = new SQLiteConnection(path))
                {
                    return connection.Find<Profile>(id);
                }
            }
            catch (SQLiteException ex)
            {
                Log.Info("SQLiteEx", ex.Message);

                return null;
            }
        }

        /// <summary>
        /// Profile tablosunda ki verileri döner.
        /// </summary>
        /// <returns></returns>
        public static List<Profile> getProfileAll()
        {
            try
            {
                using (var connection = new SQLiteConnection(path))
                {
                    return connection.Table<Profile>().ToList();
                }
            }
            catch (SQLiteException ex)
            {
                Log.Info("SQLiteEx", ex.Message);

                return null;
            }
        }
    }
}

– Şimdi MainActivity.cs classını açıp aşağıda ki gibi ilgili kodları ekleyelim:

MainActivity.cs

using Android.App;
using Android.Widget;
using Android.OS;
using System.Collections.Generic;

namespace XamarinSqliteTest
{
    [Activity(Label = "XamarinSqliteTest", MainLauncher = true)]
    public class MainActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            //Database oluşturulur.
            SQLHelper.ProfileHelper.createDatabase();

            Model.Profile profileRecord = new Model.Profile();
            profileRecord.Name = "Semih";
            profileRecord.Surname = "Çelikol";
            profileRecord.Email = "semihcelikol@outlook.com";

            //Sqlite insert ediyoruz.
            SQLHelper.ProfileHelper.insert(profileRecord);

            //Profile tablosunda ki verileri çekiyoruz.
            List<Model.Profile> listProfile = SQLHelper.ProfileHelper.getProfileAll();

            //Adapteri kullanarak verilerimizi ProfileLayout.axml dosyasında ilgili yerlere yazıyoruz.
            ProfileAdapter profileAdapter = new ProfileAdapter(this, listProfile);

            //Main.axml dosyamızda ki Listview objemizi çekiyoruz.
            ListView mainListView = FindViewById<ListView>(Resource.Id.mainListView);

            //ProfileLayout.axml dosyasında ki verileri main.axml dosyasında ki mainListview objesine atıyoruz.
            mainListView.Adapter = profileAdapter;
        }
    }
}

Evet arkadaşlar basit anlamda kullanımı bu şekildedir. Ben burada sadece kod ile 1 kayıt insert edip, bu kaydı listeledim. Bunun sonucunda benim ekran çıktım bu şekilde;

ProfileHelper.cs dosyası içinde silme işlemleri ile ilgili methodlarıda ekledim.
Bu methodu şu şekilde kullanabilirsiniz.

//Profile tablosunda ki verileri çekiyoruz.
            List<Model.Profile> listProfile = SQLHelper.ProfileHelper.getProfileAll();
bool ret = SQLHelper.ProfileHelper.deleteRecord(listProfile.Find(x => x.Name == "Semih").Id);

Burada tek dikkat etmeniz gereken nokta, silme işlemi yaptıktan sonra listProfile tekrar çekip adaptere onu göndermelisiniz. yani şu şekilde;

//Profile tablosunda ki verileri çekiyoruz.
            List<Model.Profile> listProfile = SQLHelper.ProfileHelper.getProfileAll();

            bool ret = SQLHelper.ProfileHelper.deleteRecord(listProfile.Find(x => x.Name == "Semih").Id);

            //Adapteri kullanarak verilerimizi ProfileLayout.axml dosyasında ilgili yerlere yazıyoruz.
            ProfileAdapter profileAdapter = new ProfileAdapter(this, SQLHelper.ProfileHelper.getProfileAll());

Projenin tam halini Github‘ta paylaştım, buradan erişebilirsiniz : https://github.com/semihcelikol/XamarinSqliteTest

Bu kaynaklarda yararlı olabilir, incelemenizi tavsiye ederim:

https://www.youtube.com/watch?v=3AVPhip842M

https://developer.xamarin.com/recipes/android/data/databases/sqlite/

https://developer.xamarin.com/recipes/ios/data/sqlite/create_a_database_with_sqlitenet/

Umarım yardımcı olabilmişimdir. Sorularınızı, önerilerinizi yorumlarda belirtebilirsiniz. İyi çalışmalar.

Bir Cevap Yazın