Makale Özeti

Bu makalemizde C# 3.0 la birlikte hayatımıza giren Extension Method’ların kullanımını kendi yazdığımız SqlCeUtility adlı class’in icerisinde nasıl hayat buldurabileceğimize ve her disconnected + data tutma gereksinimi olan Sql tabanlı mobile projelerde kullandığımız SQLCE erişim metodlarını bir cati altinda toplayarak tekrar tekrar yazmaktan nasıl kurtulabileceğimizi irdeleyeceğiz...

Makale

Bu makalemizde C# 3.0 la birlikte hayatımıza giren Extension Method’ların kullanımını kendi yazdığımız SqlCeUtility adlı class’in icerisinde nasıl hayat buldurabileceğimize ve her disconnected + data tutma gereksinimi olan Sql tabanlı mobile projelerde kullandığımız SQLCE erişim metodlarını bir cati altinda toplayarak tekrar tekrar yazmaktan nasıl kurtulabileceğimizi irdeleyeceğiz...

Mobil projelerde disconnected modu göz önünde bulundurduğumuz bir çok senaryoda (üretim ve lojistik de bazen tersi durumlar olabiliyor RF kullanıldığı durumların yanı sıra , bir cok ürün production ID sayesinde unique olduğu için sayımlarda sadece disconnected olan ve live dataya erişiminin olmadığı uygulamalar bahsettiğimiz senaryonun dışında kalıyor..) bağlantı kesikliğinde uygulamanın kesintiye uğramadan yola devam etmesi ve tekrar bağlantı sağlandığında live datayı güncelleyecek şekilde yapılandırılması söz konusu oluyor... ( düşünsenize bundan 4-5 yıl önce wi-fi nin PDA ve benzeri cihazlarda kullanımı mümkün değildi..Ama bugün bakıyoruz ki birçok PDA üzerinde 802.11b/g chipseti ile geliyor..Mekana konulan repeater’lar güçlü wireless bridge’la ilede km’ce alan içerisinde dahil cok rahat bir şekilde live olan data ile işlemlerini gorebiliyorlar..Bunun sadece mobile üzerine yazılan uygulama ile değil aynı zamanda daha önceki bir makalemde değindiğim terminal services ile de yapabilmek mümkün olunca farklı çözüm stratejileride beraberinde geldi.. )) İşte bu durumda bizde client’da datayi bir şekilde tutmak durumunda kalıyoruz.Efendim bu bir SQL engine, xml tabanlı dosyalar, ya da dat şeklinde txt bazlı dosyalar olabiliyor..Peki bu durumda ilişkisel bir şekilde verinin alınması ve bunun presente edilmesi konusunda mutlak ve esnek bir çözüme ihtiyacımız olduğu kesindir..C# 3.0 ve mobile üzerinde XML kullanarak ilişkisel veri modellemesi nasıl yapabileceğimize ışık tutacağım daha sonraki bir makalemde lakin su anda SQL Server’in device’lar için geliştirilmiş olan modeli SQL Server Compact Edition’ı nasıl efektif birşekilde yeni dil özellikleriyle kullanabilir bunu irdeleyeceğiz...

 

Öncelikle ilgili class’imizi tasarlamaya başlayalım..İhtiyaclar ve içerik olarak koyduğum metodlar istek dahilinde genişletilebilir , tamamen sizin elinizde...

Öncelikle mobil projemize System.Data.SqlServerCe  dll’lerini referans kısmına eklememiz lazım..Daha sonra aşağıda ki gibi ilgili class’ımızı hazırlıyoruz...

 

    public static class SqlCeEngineFxExtension

    {

        public static bool TableExist(this SqlCeEngineFx fxEngine, string tName) // ilgili tablonun veritabanında olup olmadığını kontrol ediyoruz...!

        {

            bool result = false;

 

            using (SqlCeConnection conn = new SqlCeConnection(fxEngine.ConnString))

            {  // burda gördüğümüz ConnString aslında baseclass’in içerisinde yer alan LocalConnectionString property’sinin içeriğine işaret ediyor..

                conn.Open();

                using (SqlCeCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText =

                     @"SELECT COUNT(TABLE_NAME)

       FROM INFORMATION_SCHEMA.TABLES

       WHERE TABLE_NAME=@Name";

                    cmd.Parameters.AddWithValue("@Name", tName);

                    result = Convert.ToBoolean(cmd.ExecuteScalar()); // sayı olarak dönen sonuc eşliğinde 0 olması durumunu tablonun olmadığı 1 olması ( ki fazlası olamaz J) var kabul ediyor ve ona göre olması gereken işi yapıyoruz...

                }

            }

            return result; // sonuc!

        }

        public static List<T> PopulateStringList<T>(this SqlCeEngineFx fxEngine,SqlCeCommand cmd)

        { // ilgili tabload ilgili alana ait olan bilgileri generic bir list olarak bize geri döndüren ilgili extension methodu yazıyoruz...!

            List<T> list = new List<T>();

 

            using (SqlCeDataReader reader = cmd.ExecuteReader())

            {

                while (reader.Read())

                {

                    list.Add((T)reader.GetValue(0));

                }

            }

 

            return list; // sonuc!

 }

       // burda da ilgili veritabanında yer alan tüm tabloların listesi alınıyor..

public static List<T> GetTables<T>(this SqlCeEngineFx fxEngine)

        {

            List<T> tables;

 

            using (SqlCeConnection conn = new SqlCeConnection(fxEngine.ConnString))

            {

                conn.Open();

                using (SqlCeCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";

                    tables = fxEngine.PopulateStringList<T>(cmd);

                }

            }

 

            return tables;//sonuç!

        }

 

       //İlgili db içinde tanımlanan tüm table constraint’lerin listesisini alıyoruz..

        public static List<T> GetTableConstraints<T>(this SqlCeEngineFx fxEngine)

        {

            List<T> constraints;

 

            using (SqlCeConnection conn = new SqlCeConnection(fxEngine.ConnString))

            {

                conn.Open();

                using (SqlCeCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText = "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS";

                    constraints = fxEngine.PopulateStringList<T>(cmd);

                }

            }

 

            return constraints;//sonuç!

        }

//İlgili tablo için verilen tüm constraint’lerin listesini verir. 

        public static List<T> GetTableConstraints<T>(this SqlCeEngineFx fxEngine,string tablename)

        {

            List<T> constraints;

 

            using (SqlCeConnection conn = new SqlCeConnection(fxEngine.ConnString))

            {

                conn.Open();

                using (SqlCeCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText =

                     @"SELECT CONSTRAINT_NAME

       FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS

       WHERE TABLE_NAME=@Name";

                    cmd.Parameters.AddWithValue("@Name", tablename);

                    constraints = fxEngine.PopulateStringList<T>(cmd);

                }

            }

 

            return constraints; // sonuç!

        }

        

        public static void CreateDatabase(this SqlCeEngineFx fxEngine) // db create etme.!

        {

            fxEngine.CreateDatabase();

        }

        public static void Repair(this SqlCeEngineFx fxEngine,string connectionString, RepairOption options) // ilgili objenin onarılması..

        {

            fxEngine.Repair(connectionString, options);

        }

        public static void Shrink(this SqlCeEngineFx fxEngine) // İlgili db’nin shrink edilmesi!Kullanılmayan data için shrink metodunu kullanarak tasarruf etme imkanımız bulunmaktadır..

        {

            fxEngine.Shrink();

        }

        public static bool Verify(this SqlCeEngineFx fxEngine) // Verify süreci!Fiziksel doğrulama.

        {

            return fxEngine.Verify();

 }

 

Aşağıda adı geçen kod parçasında ise extend ettiğimiz orjinal Class’imizi goruyoruz..

   public class SqlCeEngineFx : IDisposable

    {

        private SqlCeEngine fxEngine;

 

        public SqlCeEngineFx()

        {

            fxEngine = new SqlCeEngine();

        }

 

        public SqlCeEngineFx(string connectionString)

        {

            fxEngine = new SqlCeEngine(connectionString);

        }

        public string ConnString

        {

            get { return fxEngine.LocalConnectionString; // ilgili SqlCeEngine içinde yer alan LocalConnectionString property’sini farklı bir isimde dışarı açıyoruz..

            set { fxEngine.LocalConnectionString = value; }

        }

        public void Dispose()  // using bloğunda kullanabilelim diye..!

        {

            fxEngine.Dispose();

            fxEngine = null;

        }

    }

 

 

Uygulamamızın içerisinde kullanırken de   ;

resim2 bulunamadı!

Böylelikle istediğim şekilde daha sonrada kullanabileceğimiz oldukca basit bir SqlCeEngine çatısı elde etmiş olduk.

Umarım faydalı olmuştur.

Başka bir makalede görüşmek dileğiyle..

 

Kaynakça : MSDN , Christian Helle

 

Eralp Erat

MVP – Mobile Devices

MCP,MCAD.NET,MCSD.NET

http://www.eralperat.com

HIMS