Makale Özeti

Bu makalemde hepimizin veritabanı uygulaması geliştirirken karşılaştığı genel bir soruna çözüm sunmaya çalışacağım.Aslında buna işin angaryasını ortadan kaldırmak diyebiliriz.Geliştirdiğimiz veritabanı uygulamalarında en çok tekrarladığımız şey veritabanında bulunan bir tablo'ya veri göndermek ve okumak.Baz anlamda bu işleri sıralarsak;

Makale


Yeni oluşturacağımız bu sınıfın ismi TableAccess olsun.

İlk olarak select SQL cümlesinin otomasyonunu , TableAccess e gönderilecek Table nesnesini ve bu nesnenin attibute değerlerini barındıracak üyeleri yazalım.

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Reflection;
using System.Collections;
using System.ComponentModel;

public class TableAccess
{
    public TableAccess()
    {
    }
    public TableAccess(object tableobject)
    {
        this.TableObject = tableobject;
    }

    #region Variables
    private string mConnectionString="";//veritabanı ile kurulacak bağlantının tutulduğu alan.
    private object mTableObject;	//Table nesnesini tutan alan. (Ör: User nesnesi)
    private string mTableName;		//TableObject nesnesinin değerlerinin tutulduğu alan.
    private CommandType mTypeofSaveCommand; //TableObject nesnesinin değerlerinin tutulduğu alan.
    private CommandType mTypeofDeleteCommand; //TableObject nesnesinin değerlerinin tutulduğu alan.
    private string mSPNameforSave; //TableObject nesnesinin değerlerinin tutulduğu alan.
    private string mSPNameforDelete; //TableObject nesnesinin değerlerinin tutulduğu alan.
    #endregion Variables

    #region GetSets
    public string ConnectionString
    {
        get { return mConnectionString; }
        set { mConnectionString = value; }
    }
    public object TableObject
    {
        get { return mTableObject; }
        set 
        {
	    //bir tableobject nesnesi atandığında sınıfın attrib değerleri okunarak 
            //değerler yerel alanlara aktarılıyor.
            mTableObject = value;
            object[] o = mTableObject.GetType().GetCustomAttributes(typeof(AttribTableObject), false);
            foreach (object m in o)
            {
                AttribTableObject ma = (AttribTableObject)m;
                mTableName = ma.TableName;                    
                mSPNameforSave = ma.SPNameforSave;
                mTypeofSaveCommand = ma.TypeofSaveCommand;
                mTypeofDeleteCommand = ma.TypeofDeleteCommand;
                mSPNameforDelete = ma.SPNameforDelete;
            }
        }
    }
    #endregion GetSets

    public DataSet Select(string SelectColumns,string SQLFromPart,string SQLWherePart,string SQLOrderPart)
    {
        StringBuilder mSQL = new StringBuilder();
        SqlCommand comSQL = new SqlCommand();
        comSQL.CommandType = CommandType.Text;

	if (SelectColumns.Trim().Length==0)
            SelectColumns="*";
        
	//SQLFromPart parametresi boş değere sahipse standart işlem uygulanıp
        //Attribute dan okunan değer ile SQL cümlesinin from kısmı oluşturuluyor.
	//Eğer SQLFromPart parametresi gönderilmişse bu değer kullanılıyor.
        if(SQLFromPart.Trim().Length==0)
            mSQL.Append("SELECT " + SelectColumns + " FROM " + mTableName + " WHERE ");
        else
            mSQL.Append("SELECT " + SelectColumns + " FROM " + SQLFromPart + " WHERE ");

	//reflection sınıfı kullanılarak nesne özelliklerine erişiliyor.
        //her üyenin AttribDataAccess türünden nitelikleri okunuyor.
        #region ReadAssemblyInformation
        Type t = mTableObject.GetType();
        MemberInfo[] mi = t.GetMembers();
        foreach (MemberInfo m in mi)
        {
            object[] o = m.GetCustomAttributes(typeof(AttribDataAccess), true);
            foreach (object ma in o)
            {
                AttribDataAccess d = (AttribDataAccess)ma;

		//Eğer alan select işleminde kullanılmak üzere işaretlenmişse
                if (d.IsUsedInSelect)
                {
		    //TableObject nesnesinin üye değeri returnValue değerine aktarılıyor. 
                    object returnValue = null;
                    returnValue = t.InvokeMember(m.Name,
                        BindingFlags.GetProperty,
                        null, mTableObject, new object[] { });

		    //Üyenin değeri NullValue nesnesine eşitse returnValue değeri null olarak atanıyor.
                    if (returnValue != null && d.NullValue != null)
                        if (returnValue.ToString()==d.NullValue.ToString())
                            returnValue = null;

		    //SqlDbType enum'unda bulunan DateTime türüne select cümlesi yazarken 
		    //gerekli ayrıştırmalar yapılıyor.Saat bilgisi tutuluyorsa parametre olarak
                    //ekleniyor.
                    switch (d.DatabaseType)
                    {
                        case SqlDbType.DateTime:                                
                            if (returnValue.ToString() == DateTime.MinValue.ToString())
                                returnValue = null;
                            if (returnValue != null)
                            {
                                SqlParameter paramSQL;

                                string strDbColumnName = "";
                                if (d.DatabaseColumnName.Length == 0)
                                    strDbColumnName = m.Name;
                                else
                                    strDbColumnName = d.DatabaseColumnName;
                                
                                mSQL.Append("Day(" + strDbColumnName + ")=@Day_" + strDbColumnName + " AND ");
                                paramSQL = new SqlParameter("@Day_" + strDbColumnName, Convert.ToDateTime(returnValue).Day);
                                comSQL.Parameters.Add(paramSQL);
                                mSQL.Append("Month(" + strDbColumnName + ")=@Month_" + strDbColumnName + " AND ");
                                paramSQL = new SqlParameter("@Month_" + strDbColumnName, Convert.ToDateTime(returnValue).Month);
                                comSQL.Parameters.Add(paramSQL);
                                mSQL.Append("Year(" + strDbColumnName + ")=@Year_" + strDbColumnName + " AND ");
                                paramSQL = new SqlParameter("@Year_" + strDbColumnName, Convert.ToDateTime(returnValue).Year);
                                comSQL.Parameters.Add(paramSQL);

				//Eğer saat bilgisi 00:00:00 dan farklıysa gerekli parametreler
				//yaratılıyor.
                                if ((Convert.ToDateTime(returnValue).Hour +
                                    Convert.ToDateTime(returnValue).Minute +
                                    Convert.ToDateTime(returnValue).Second) > 0)
                                {
                                    mSQL.Append("Datepart(hh," + strDbColumnName + ")=@Hour_" + strDbColumnName + " AND ");
                                    paramSQL = new SqlParameter("@Hour_" + strDbColumnName, Convert.ToDateTime(returnValue).Hour);
                                    comSQL.Parameters.Add(paramSQL);
                                    mSQL.Append("Datepart(mi," + strDbColumnName + ")=@Minute_" + strDbColumnName + " AND ");
                                    paramSQL = new SqlParameter("@Minute_" + strDbColumnName, Convert.ToDateTime(returnValue).Minute);
                                    comSQL.Parameters.Add(paramSQL);
                                    mSQL.Append("Datepart(ss," + strDbColumnName + ")=@Second_" + strDbColumnName + " AND ");
                                    paramSQL = new SqlParameter("@Second_" + strDbColumnName, Convert.ToDateTime(returnValue).Second);
                                    comSQL.Parameters.Add(paramSQL);
                                }
                                returnValue = null;
                            }
                            break;                            
                    }

		    //Eğer üye bilgisi null değerinden farklı bir değere sahipse parametre
		    //nesnesi yaratılıyor.
                    if (returnValue != null)
                    {
                        SqlParameter paramSQL;

			//Üye WildChar uygulanmak üzere işaretlenmişse SQL cümlesi
			//LIKE ile oluşturuluyor.
                        string strEqualsSign;
                        if (d.IsWildCharImplemented)
                        {
                            returnValue = (object)returnValue.ToString().Replace("*", "%");
                            strEqualsSign = " LIKE ";
                        }
                        else
                        {
                            strEqualsSign = "=";
                        }

			//Eğer DatabaseColumnName değeri boş ise reflection ile okunan
			//değer atanıyor ve parametre yaratılıyor.
                        if (d.DatabaseColumnName.Length == 0)                                
                        {                                
                            mSQL.Append(m.Name + strEqualsSign + "@" + m.Name + " AND ");                                
                            paramSQL=new SqlParameter("@" + m.Name,returnValue);
                        }
                        else
                        {
                            mSQL.Append(d.DatabaseColumnName + strEqualsSign + "@" + d.DatabaseColumnName + " AND ");
                            paramSQL=new SqlParameter("@" + d.DatabaseColumnName,returnValue);
                        }

			//Sonuç olarak parametre ekleniyor.
                        comSQL.Parameters.Add(paramSQL);
                    }
                }
            }
        }
        #endregion ReadAssemblyInformation

	//hiçbir üyeye değer atanmamışsa SQL cümlesinin sonu WHERE ile biter
 	//Ayrıca her koşuldan sonra bir sonraki koşul için AND sözcüğü cümlede
	//bırakılmıştır.Bu kontroller yapılıp SQL cümlesinin son halini alması
	//sağlanıyor.
        #region TrimSQL
	if (SQLWherePart.Trim().Length > 0)
            mSQL.Append(SQLWherePart);

        string mSQLRelease = mSQL.ToString();
        if (mSQLRelease.Substring(mSQLRelease.Length - 7, 7) == " WHERE ")
            mSQLRelease = mSQLRelease.Replace(" WHERE ", "");
        if (mSQLRelease.Substring(mSQLRelease.Length - 5, 5) == " AND ")
            mSQLRelease = mSQLRelease.Substring(0, mSQLRelease.Length - 5);

        if (SQLOrderPart.Trim().Length > 0)
            mSQLRelease+=" ORDER BY " + SQLOrderPart;
        #endregion TrimSQL

	//Son olarak SQL cümlemiz çalıştırılıyor
        #region DoConnectionAndAction
        SqlConnection conSQL = new SqlConnection(mConnectionString);
        comSQL.CommandText = mSQLRelease;            
                    
        DataSet dsSQL = new DataSet();
        try
        {
            conSQL.Open();
            comSQL.Connection = conSQL;
            SqlDataReader drdSQL = comSQL.ExecuteReader();
            dsSQL.Load(drdSQL,LoadOption.OverwriteChanges,mTableName);                
            return dsSQL;
        }
        catch (Exception excpSQL)
        {
            throw excpSQL;
        }
        #endregion DoConnectionAndAction
    }
    //Aşırı yüklemeler
    public DataSet Select(string SelectColumns, string SQLFromPart,string SQLWherePart)
    {
        return Select(SelectColumns, SQLFromPart, SQLWherePart, "");
    }
    public DataSet Select(string SelectColumns, string SQLFromPart)
    {
        return Select(SelectColumns, SQLFromPart, "", "");
    }
    public DataSet Select(string SelectColumns)
    {
        return Select(SelectColumns, "", "", "");
    }
    public DataSet Select()
    {
        return Select("*", "","","");
    }
}

Kodu elimden geldiği kadar açıklayıcı yazmaya çalıştım.Umarım anlaşılmayan yer yoktur.

Artık kodumuz kullanıma hazır.Isterseniz bir select denemesi yapalım.

User u =new User();            
TableAccess ta = new TableAccess(u);
ta.ConnectionString = @"Data Source=IT001\SQLEXPRESS;Initial Catalog=TestDatabase;Integrated Security=True";
DataSet ds = ta.Select();

dataGridView1.DataSource = ds;
dataGridView1.DataMember = u.TableName;

Şimdi olayı biraz daha karmaşıklaştıralım ve bir koşul belirtelim.Kullanıcı ismi (USR_NAME) '%eve%' koşuluna uyan kayıtları sorgulayalım.Dikkat edin bu işlem için ne sql sorgusu yazıyoruz ne de yeni parametreler oluşturuyoruz.

User u =new User();            
u.USR_NAME="*eve*";
TableAccess ta = new TableAccess(u);
ta.ConnectionString = @"Data Source=IT001\SQLEXPRESS;Initial Catalog=TestDatabase;Integrated Security=True";
DataSet ds = ta.Select();

dataGridView1.DataSource = ds;
dataGridView1.DataMember = u.TableName;

Değişiklik yaptığımız sadece 1 satır mevcut.Ayrıca user sınıfındaki birden fazla üyeyi kullanarak sorgulamamızın kriterlerlerini oluşturabiliriz veya sıralama koşulu belirtebiliriz.

User u =new User();
TableAccess ta = new TableAccess(u);
ta.ConnectionString = @"Data Source=IT001\SQLEXPRESS;Initial Catalog=TestDatabase;Integrated Security=True";
DataSet ds = ta.Select("", "", "", "USR_NAME DESC");

dataGridView1.DataSource = ds;
dataGridView1.DataMember = u.TableName;


Levent YILDIZ
theone@leventyildiz.net
msmoracle@hotmail.com