Arşiv

Etiketlenen yazılar ‘code’

C# İsimsiz Tipler – Anonymous Types

Sadece bir method içerisinde kullanacağınız basit class‘lara kaç defa ihtiyaç duydunuz? Böyle bir class’a her ihtiyaç duyduğunuzda yapmanız gereken, yeni bir class oluşturup, bütün tanımlama kodlarını (private alanlar, public alanlar, vs.) yazmaktır.

C# dili, İsimsiz Tip (Anonymous Type) tanımlamaya izin veriyor. Üstelik, private ve public öğelerin oluşturulmasını ve yönetilmesini C# dilinin kendisi üstleniyor.

public class HataLogla()
{
	var Hata = new { Mesaj = "Hata Mesajının Kendisi", Tarih = DateTime.Now, Yer = "XClass.YMethod" };
	var Kullanici = new { Id = 42, AdSoyad = "Engin Polat", Yonetici = "Ali Veli" };

	string Loglanacak = string.Format("Hata Mesajı: {0}\nTarih: {1} {2}\nHatanın Oluştuğu Yer: {3}\n\nKullanıcıId: {4}\nKullanıcı Adı: {5}\nYöneticisi: {6}", Hata.Mesaj, Hata.ToShortDateString(), Hata.Tarih.ToLongTimeString(), Hata.Yer, Kullanici.Id, Kullanici.AdSoyad, Kullanici.Yonetici);

	File.WriteAllText(Loglanacak, @"C:\Log\Log.txt");

	MessageBox.Show(Hata.Mesaj, Hata.Tarih);
}

Yukarıdaki kodda yer alan Hata ve Kullanici değişkenlerinin tipleri, derleme zamanında derleyici tarafından otomatik oluşturulur. Eğer method‘un içerisine aşağıdaki kodları eklersek;

MessageBox.Show("Hata değişkeninin tipi : " + Hata.GetType().ToString());
MessageBox.Show("Kullanici değişkeninin tipi : " + Kullanici.GetType().ToString());

Mesaj kutularında şu değerleri görürüz;

Hata değişkeninin tipi : <>f_AnonymousType0′3[System.String,System.DateTime,System.String]
Kullanici değişkeninin tipi : <>f_AnonymousType0′3[System.Int32,System.String,System.String]

Farkettiğiniz gibi, böyle bir tip oluşturmaya çalışırsak, derleme zamanında hata alırız, ama C# derleyicisi bizim için bu tipleri oluşturuyor.

Değişkenin tipini veremeyeceğimiz için, C# diline var anahtar kelimesi eklenmiştir.

var anahtar kelimesi sayesinde, değişkenin tipi atandığı değerden otomatik olarak çözümleniyor.

İsimsiz Tipler (Anonymous Types) IDisposable interface’ini uygulamadığı için, Disposable olamazlar.

Eğer yukarıdaki örneği geleneksel kodlama teknikleri ile yazacak olsaydık;

public class HataBilgi
{
	private string _Mesaj = string.Empty;
	private DateTime _Tarih = DateTime.Now;
	private string _Yer = string.Empty;

	public string Mesaj
	{
		get
		{
			return _Mesaj;
		}
		set
		{
			_Mesaj = value;
		}
	}

	public DateTime Tarih
	{
		get
		{
			return _Tarih;
		}
		set
		{
			_Tarih = value;
		}
	}

	public string Yer
	{
		get
		{
			return _Yer;
		}
		set
		{
			_Yer = value;
		}
	}

	public HataBilgi(string Mesaj, DateTime Tarih, string Yer)
	{
		this.Mesaj = Mesaj;
		this.Tarih = Tarih;
		this.Yer = Yer;
	}
}

public class KullaniciBilgi
{
	private int _Id = 0;
	private string _AdSoyad = string.Empty;
	private string _Yonetici = string.Empty;

	public int Id
	{
		get
		{
			return _Id;
		}
		set
		{
			_Id = value;
		}
	}

	public string AdSoyad
	{
		get
		{
			return _AdSoyad;
		}
		set
		{
			_AdSoyad = value;
		}
	}

	public string Yonetici
	{
		get
		{
			return _Yonetici;
		}
		set
		{
			_Yonetici = value;
		}
	}

	public KullaniciBilgi(int Id, string AdSoyad, string Yonetici)
	{
		this.Id = Id;
		this.AdSoyad = AdSoyad;
		this.Yonetici = Yonetici;
	}
}

public class HataLoglama
{
	HataBilgi Hata = new HataBilgi("Hata Mesajının Kendisi", DateTime.Now, "XClass.YMethod");
	KullaniciBilgi Kullanici = new KullaniciBilgi(42, "Engin Polat", "Ali Veli");

	string Loglanacak = string.Format("Hata Mesajı: {0}\nTarih: {1} {2}\nHatanın Oluştuğu Yer: {3}\n\nKullanıcıId: {4}\nKullanıcı Adı: {5}\nYöneticisi: {6}", Hata.Mesaj, Hata.ToShortDateString(), Hata.Tarih.ToLongTimeString(), Hata.Yer, Kullanici.Id, Kullanici.AdSoyad, Kullanici.Yonetici);

	File.WriteAllText(Loglanacak, @"C:\Log\Log.txt");

	MessageBox.Show(Hata.Mesaj, Hata.Tarih);
}

İsimsiz Tip yeteneklerini kullanarak yazdığımızda ise;

public class HataLogla()
{
	var Hata = new { Mesaj = "Hata Mesajının Kendisi", Tarih = DateTime.Now, Yer = "XClass.YMethod" };
	var Kullanici = new { Id = 42, AdSoyad = "Engin Polat", Yonetici = "Ali Veli" };

	string Loglanacak = string.Format("Hata Mesajı: {0}\nTarih: {1} {2}\nHatanın Oluştuğu Yer: {3}\n\nKullanıcıId: {4}\nKullanıcı Adı: {5}\nYöneticisi: {6}", Hata.Mesaj, Hata.ToShortDateString(), Hata.Tarih.ToLongTimeString(), Hata.Yer, Kullanici.Id, Kullanici.AdSoyad, Kullanici.Yonetici);

	File.WriteAllText(Loglanacak, @"C:\Log\Log.txt");

	MessageBox.Show(Hata.Mesaj, Hata.Tarih);
}

Aradaki fark açıkça ortada!

C# 3.0 Object Initializer Özelliği

C# 3.0 object initialize etmek için kodda kısaltma sağlayacak bir yenilik sunuyor. Hemen hergün aşağıdaki gibi kod yazmamız gerekmez mi?

Personel UygulamaGelistirici = new Personel();
UygulamaGelistirici.Id = 42;
UygulamaGelistirici.AdSoyad = "Engin Polat";
UygulamaGelistirici.Birim = "NTV - Yeni Medya";

Personel sınıfından yeni bir örnek oluşturduktan sonra, sınıfın özelliklerinden ihtiyacımız olanlara atamalar yapmaya başlarız.

Eğer Personel sınıfının constructor‘ı olsaydı ve bu özelliklerin atamalarını yapsaydı, tek bir satırda, hem Personel sınıfının yeni bir örneğini UygulamaGelistirici değişkenine oluşturmuş, hem de bazı özelliklerin değerlerini atamış olabilirdik.

Fakat, Personel sınıfının constructor‘ını yazamadığımız durumlarda veya constructor‘da parametreler ile almak için çok fazla özellik olduğu durumlarda bu yöntemi kullanamayız.

C# 3.0 ile birlikte Object Initializer denilen yeni bir kodlama tekniği tanıtıldı.

Hemen yukarıdaki örneği bu teknik ile yazalım;

Personel UygulamaGelistirici = new Personel() { Id = 42, AdSoyad = "Engin Polat", Birim = "NTV - Yeni Medya" };

Gördüğünüz gibi, kodlama bizim için kolaylaşıyor.

Object Initializer içerisinde sadece özelliklere atama yapabiliyoruz, method çağrımı vs. yapılamıyor.

Eğer sınıfın özellikleri başka sınıflardan örnekler istiyorsa, Object Initializer nasıl yazabiliriz? Aşağıdaki gibi yazabiliriz;

VeritabaniSorgulayici dbSorgu = new VeritabaniSorgulayici() {
	Connection = new SqlConnection("..ConnectionString.."),
	Command = new SqlCommand("..Sorgu..")
};

C# Obsolete Attribute

Yaklaşık olarak .Net Framework içerisinde binlerce class ve binlerce class içerisinde milyonlarca method vardır.

Her yeni .Net Framework versiyonunda bu class‘ların ve method‘ların bir kısmı yeni yöntemler / yeni teknikler ile baştan yazılıyor.

Bazen bu değişiklikler o kadar büyük oluyor ki, ilgili class veya method yeni bir isimle baştan yazılıyor ve eskisinin artık kullanılmaması öneriliyor.

Önceki Framework versiyonlarında yanlış konumlandırdıkları class veya method‘ları taşıdıkları durumlarda da aynı durum geçerli.

Geriye yönelik uyumluluktan dolayı, kullanılmaması önerilen class veya method‘lar üç versiyon daha yerinde durmaya devam eder.

Ama derleme zamanında uygulama geliştiriciye, ilgili class veya method‘un Obsolete olduğunu bildirir ve kodunu güncellemesini ister.

Bu özellik Obsolete Attribute sayesinde sağlanır.

Eğer biz de yazdığımız projelerimizde çeşitli class veya method’ları Obsolete yapmak istersek, aşağıdaki kodda gözüktüğü gibi yapabiliriz;

[Obsolete]
public class EskimisClass
{
	///
}

veya

[Obsolete("Bu method v4.5 versiyonundan itibaren kaldırılacak, lütfen yerine Ntv.YeniMedya.Veritabani sınıfında bulunan Baglan() methodunu kullanın. Ayrıntılı bilgi için http://www.xyz.com/Baglan sayfasına bakabilirsiniz")]
public void VeritabaniBaglan()
{
	///
}

Yukarıdaki kodda bulunan VeritabaniBaglan() method’unu kullanırken ve projemizi derlerken aşağıdaki ekranlar ile karşılaşırız;

Obsolete Method

Obsolete Method Error

C# Partial Method Desteği

C# 3.0 ile gelen partial keyword’u sayesinde partial class tanımlayabiliyoruz.

partial keyword’unun pek bilinmeyen bir kullanım alanı ise method‘lardır.

partial class tanımlayabildiğimiz gibi partial method‘da tanımlayabiliyoruz.

partial class‘ları tanımlamamızdaki en büyük fayda, kod üreticiler olmuştur. partial method tanımlamanın güzelliği de işte burada. Bir kod üreticisi ile otomatik olarak kod ürettirirken, partial method‘lar ürettirebiliriz.

Eğer üretilmiş partial method‘u uygulamazsanız, ilgili partial method‘u çağıran kod parçaları hata vermiyor.

Basitçe, uygulanmamış partial method çağrıları derleme (compile) sırasında yok sayılıyor.

Ama partial method‘lar için bazı kısıtlamalar ve kurallar var;

  • partial method’ların geri dönüş tipi herzaman void olmalıdır
  • partial method’lar out parametreler alamazlar, ama ref parametreler alabilirler
  • partial method’lar extern olamazlar
  • partial method’lar erişim belirleyici alamazlar, çünkü herzaman private erişim belirleyicisine sahiptirler
  • partial method’lar virtual olamazlar
  • partial method’lar static olabilir
  • partial method’lar generic olabilir
  • partial method’lara delegate bağlanamaz, çünkü partial method’un çalışma zamanında (runtime) var olacağı garanti değildir

Bu bilgilerden sonra örnek bir class yazalım;

public partial class DataAccessLayer
{
	partial void ResetConnection();
}

public partial class DataAccessLayer
{
	partial void ResetConnection()
	{
		///Connection'ı resetleyen kod
	}

	public void Reset()
	{
		ResetConnection();
	}
}

Gördüğünüz gibi, Reset() isminde public bir method yazmam gerekti. Çünkü, ResetConnection() method‘u partial olduğu için private erişim belirleyicisine sahip.

Eğer yukarıdaki kodun exe/dll dosyasına ILDASM tool’u bakarsak, DataAccessLayer.ResetConnection() private method’unu ve Reset() method‘u içerisinde bu method’u çağıran kod parçasını görürüz.

Eğer ResetConnection() method’unu uyguladığımız kod parçasını sildikten sonra, ILDASM ile bakarsak, DataAccessLayer.ResetConnection() private method’unun bulunmadığını ve Reset() method’unda bu method’u çağıran kod parçası olmadığını görürüz.

Böylece çalışma zamanı hatası almayız.

C# Auto-Implemented Properties Özelliği

Uygulamalarımızı geliştirirken birçok class veya struct yazmamız gerekir.

Bu class veya struct‘ların hemen hepsinde özelliklere (properties) ihtiyaç duyarız.

Çünkü, local değişkenlerin public değil, private olmasını isteriz. Bu durumda yapmamız gereken public olmasını istediğimiz local değişkenlere birer tane özellik (property) yazmaktır.

Örnek Personel Class‘ı aşağıdaki gibi olacaktır;

public class Personel
{
	private int PersonelId;
	private string AdSoyad;
}
public class Personel
{
	private int _PersonelId;
	private string _AdSoyad;

	public int PersonelId
	{
		get { return _PersonelId; }
		set { _PersonelId = value; }
	}

	public string AdSoyad
	{
		get { return _AdSoyad; }
		set { _AdSoyad = value; }
	}
}

Sadece okuma/yazma yapan iki özellik için ne faz kod yazdık, değil mi?

Eğer get/set blokları arasına özel iş yapan kod yazmamız gerekiyorsa, yukarıdaki gibi yapmaya devam etmeliyiz.

Fakat sadece okuma/yazma yapan özellikleri C# 3.0‘dan itibaren daha kısa yazabiliyoruz;

public class Personel
{
	public int PersonelId { get; set; }

	public string AdSoyad { get; set; }
}

Gördüğünüz gibi local değişkenlerin oluşturulması ve yönetilmesi işini yapmakla uğraşmıyoruz.

Eğer local değişkenlerin nasıl oluşturulduğunu merak ediyorsanız, projenizi compile ettikten sonra, ortaya çıkan exe/dll dosyasını ILDASM (Intermediate Language Disassembler) tool’u ile açıp bakabilirsiniz.

PersonelId özelliği için <>k__AutomaticallyGeneratedPropertyField0 isimli bir değişkenin oluşturulduğu ve tipininde int olduğunu göreceksiniz.

Otomatik oluşturulan değişken’in ismini herhangi bir kod parçasında kullanmaya çalışırsak, derleme (compile) zamanında yazım hatası (syntax error) alırız, yani local değişkenleri kullanamayız.

Eski stil kodlamada sadece okunabilir (readonly) veya sadece yazılabilir (writeonly) property tanımlayabiliyorduk. Bunu yeni stil kodlamada da yapabilir miyiz?

Cevap Evet, aşağıdaki kodu inceleyin;

public class Personel
{
	public int PersonelId { get; private set; }
	public string AdSoyad { private get; set; }
}

C# ile Tarihin Gününü Bulma

Uygulamanızda tarih göstereceğiniz ekranlarda, tarihin gününü de göstermek istersiniz. Hatta gün isimlerinin, kullanıcının dilinde olmasını istersiniz.

Öncelikle ilgili tarihin hangi güne geldiğini bulalım;

int gun1 = (int)DateTime.Now.DayOfWeek;
int gun2 = (int)DateTime.Now.AddMonth(-5).DayOfWeek;
int gun3 = (int)DateTime.Parse("2009-01-05").DayOfWeek;

Dikkat etmemiz gereken şey; DayOfWeek ilgili tarihin hangi güne denk geldiğini bulurken, Pazar gününü baz alır.

Uygulamayı kullanan kullanıcının kendi dilinde gün ismini bulmak için;

string gun1 = DateTime.Now.ToString("dddd");
string gun2 = DateTime.Now.DayOfWeek;
string gun3 = DateTime.Parse("2009-01-05").DayOfWeek;
string gun4 = CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int)DateTime.Now.DayOfWeek];

İlgili tarihin hangi güne geldiğini başka bir dilde bulmak için;

string gun5 = CultureInfo.GetCultureInfo("tr-TR").DateTimeFormat.DayNames[(int)DateTime.Now.DayOfWeek];
string gun6 = CultureInfo.GetCultureInfo("de-DE").DateTimeFormat.DayNames[(int)DateTime.Now.DayOfWeek];

C# Null Coalescing (??) Operatörü

Null Coalescing Operatörü (??) C# dilinin gözden kaçan, ama çok kullanışlı bir operatörüdür.

?? operatörü sayesinde bir değişkenin değerinin null olduğu durumda alternatif değer döndürebiliriz.

string mesaj = "merhaba dünya!";
string sonuc = mesaj ?? "mesaj yok";

Eğer mesaj değişkeni null değer içeriyor olsaydı, sonuc değişkenine “mesaj yok” değeri atanacaktı.

string mesaj = null;
string sonuc = mesaj ?? "mesaj yok";
int? yas = 30;
int sonuc = yas ?? -1;

Eğer yas değişkeni null ise, sonuc değişkenine -1 değeri ata.

int? yas = null;
int sonuc = yas ?? -1;

Sql Server COUNT ve COUNT_BIG Fonksiyonları

COUNT() sistem fonksiyonu, parametre olarak aldığı alandaki satır sayısını INT tipinde geri döndürür.

COUNT_BIG() sistem fonksiyonunun COUNT() fonksiyonundan farkı, elde ettiği sonucu BIGINT tipinde geri döndürmesidir.

INT veritipinin sınırları : -2^31 (-2,147,483,648) – 2^31-1 (2,147,483,647)

BIGINT veritipinin sınırları : -2^63 (-9,223,372,036,854,775,808) – 2^63-1 (9,223,372,036,854,775,807)

Eğer elde edeceğiniz sonucun INT veritipinin sınırlarına sığmayacağını düşünüyorsanız, yapmanız gereken COUNT_BIG() fonksiyonunu kullanmaktır.

Sql Server 2008′de Çoklu Insert İşlemi

19 Ocak 2010 engin.polat 1 Yorum

Sql Server 2008 ile birlikte Çoklu Insert (Multiple Insert) özelliği de hayatımıza giriyor.

Microsoft bu özelliğin altında yatan tekniğe, “Table Value Costructor” adını vermiş.

Çoklu Insert (Multiple Insert) özelliği sayesinde Insert yapan DML cümlelerinde, birden fazla satırı işleme tabi tutabiliyoruz.

AdventureWorks 2008 veritabanında bulunan HumanResources.Department tablosunda bu özelliği nasıl kullanabileceğimizi bir örnek ile inceleyelim;

INSERT INTO
	HumanResources.Department
VALUES
	('İnsan Kaynakları', 'IK', GETDATE()),
	('Bilgi İşlem', 'IT', GETDATE()),
	('Muhasebe', 'MUH', GETDATE()),
	('Finans', 'FIN', GETDATE()),
	('Lojistik', 'LOJ', GETDATE()),
	('Kalite ve Eğitim', 'KVE', GETDATE())

Kısa Sınav – 11

Yazdığınız uygulamanın bir yerinde, kullanıcının önüne otomatik olarak IkinciUygulama.exe isimli başka bir programı otomatik olarak açtırmak istiyorsunuz.

Uygulamanızın, kullanıcının IkinciUygulama.exe uygulamasını kullanmasını ve kapatmasını beklemesi gerekmektedir.

Aşağıdaki seçeneklerden hangisi bu işi tam doğru olarak gerçekleştirir?

  • Process p = new Process();
    p.StartInfo.FileName = "IkinciUygulama.exe";
    p.Start();
    p.WaitForExit(10000);
  • Process p = new Process();
    p.StartInfo.FileName = "IkinciUygulama.exe";
    p.Start();
    p.WaitForExit();
  • Process p = new Process("IkinciUygulama.exe");
    p.Start();
    p.WaitForExit(10000);
  • Process p = new Process("IkinciUygulama.exe");
    p.Start();
    p.WaitForExit();

Sorunun doğru cevabı için; Devamını Oku…

String tipinde değişkenin hafızada kapladığı alan

Hangi .Net yazılımcısına sorsanız, string tipinde değişkenin hafızada kapladığı yeri hesaplamak için, karakter sayısını 2 ile çarpmak gerektiğini söyler (UTF-8 kodlama).

Genel olarak kabul gören bu hesaplama yöntemi, birçok durumda gerçeğe çok yakın sonuç üretir. Fakat sonuç tam olarak doğru değildir.

UTF-8 (Unicode Transformation Format) hakkında daha fazla bilgiyi Wikipedia‘da yeralan şu makale‘den edinebilirsiniz.

Peki string değişkenin hafızada kapladığı alanı tam olarak nasıl hesaplayacağız?

string OrnekString = "ἄλφα βῆτα γάμμα δέλτα deneme test";
MessageBox.Show("Uzunluk * 2: " + OrnekString.Length * 2 + " Byte");
MessageBox.Show("Gerçek uzunluk: " + Encoding.UTF8.GetByteCount(OrnekString).ToString() + " Byte");

OrnekString.Length * 2: 66 Byte değerini üretirken,

Encoding.UTF8.GetByteCount(OrnekString): 53 Byte değerini üretmiştir.

String değişkenlerin hafızada kapladığı alanı tam olarak hesaplamanız gerektiği durumlarda, Encoding.UTF8.GetByteCount() fonksiyonunu kullanmanızı öneririm.

Listede Filtreleme Yapmanın İyi – Kötü – Çirkin Yolu

15 Ocak 2010 engin.polat 1 Yorum

Bütün gün, dizilerde filtrelemeler yaptıktan sonra, bu konu ile ilgili bir yazı yazmaya karar verdim. Elimizde bir List<int> olsun, dizideki 0‘dan büyük rakamları döndüren fonksiyon yazmak istediğimizi varsayalım;

Önce Kötü Yol;

private static List<int> FiltrelemeninKotuYolu(List<int> t)
{
	List<int> arrReturn = new List<int>();
	foreach (int i in t)
	{
		if (i > 0)
		{
			arrReturn.Add(i);
		}
	}
	return arrReturn;
}

Umarım artık böyle kodlar yazmıyorsunuzdur!!..

Çirkin Yol;

Önce bir Predicate Function tanımlarız;

private static bool Karsilastir(int i)
{
	if (i > 0)
	{
		return true;
	}
	return false;
}

Sonra, Predicate Function‘ı kullanırız;

private static List<int> FiltrelemeninCirkinYolu(List<int> t)
{
	Predicate<int> pred = new Predicate<int>(Karsilastir);
	return t.FindAll(pred);
}

Kötü Yol‘dan daha doğru olduğu ortada, ama Güzel bir yol değil.

Son olarak İyi Yol;

private static List<int> FiltrelemeninIyiYolu(List<int> t)
{
	return t.FindAll(n => n > 0);
}

İyi Yol aslında sadece Çirkin Yol‘un iyileştirilmiş hali. Predicate Method kullanacağımıza Lambda Expression kullanıyoruz. n => n > 0 : n‘nin 0‘dan büyük olduğu durumlar anlamına geliyor.

Bu kodda ne yanlış var? – 2

15 Ocak 2010 engin.polat 2 comments

Aşağıdaki kod parçasını çalıştıralım. Sifir isimli değişkenin değerine baktığımızda 0 olduğunu görüyoruz.

List arrListe = new List(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
int Sifir = arrListe.Find(
	delegate(int i) {
		return i == 0;
	}
);

Listede 0 değeri yok!. Neden sonuç 0 dönüyor? Bu kodu nasıl düzeltebiliriz?

Categories: C#, Programlama Tags: , , , , , , , ,

Sql Server’da En Meşgul Veritabanını Bulmak

Geçenlerde bir öğrencimin sorusu üzerine Sql Server’da en meşgul veritabanını nasıl bulabiliriz, sorusuna cevap arayacağız.

En meşgul veritabanı, muhtemelen en çok disk operasyonu yapan veritabanıdır diye düşünerek, en çok disk aktivitesinde bulunan veritabanını yakalamaya çalışmalıyız.

Sql Server ile ilgili aradığımız birçok sorunun cevabını DMV‘lerde olduğu için, öncelikle logical_read ve logical_write miktarlarını veren DMV bulmalıyız.

MSDN’de şu sayfadan detaylı bilgiye ulaşabileceğiniz SYS.DM_EXEC_QUERY_STATS, ihtiyacımız olan TOTAL_LOGICAL_READS, TOTAL_LOGICAL_WRITES, SQL_HANDLE isminde üç kolona sahip.

SQL_HANDLE kolonunda yer alan veriyi, veritabanını bulmak için kullanabiliriz. Yapmamız gereken SYS.DM_EXEC_SQL_TEXT DMF‘i ile CROSS JOIN işlemine tabi tutarak, DBID kolonuna erişmek. Böylece DB_NAME sistem fonksiyonu sayesinde veritabanının ismine ulaşabiliriz.

SELECT
	SUM(EQS.TOTAL_LOGICAL_READS) AS TOPLAM_OKUMA,
	SUM(EQS.TOTAL_LOGICAL_WRITES) AS TOPLAM_YAZMA,
	ISNULL(DB_NAME(EST.DBID), 'AdhocSQL') AS VERITABANI
FROM
	SYS.DM_EXEC_QUERY_STATS AS EQS
	CROSS APPLY SYS.DM_EXEC_SQL_TEXT(EQS.SQL_HANDLE) AS EST
GROUP BY
	DB_NAME(EST.DBID)

C# ile Kes-Kopyala-Yapıştır Olaylarını Fırlatan Textbox

.Net Framework’ün Textbox‘ı bir çok kullanışlı event‘i kullanımımıza sunmuştur. Böylece programcılar olarak kod yazmak için seçebileceğimiz geniş bir olay kütüphanesi vardır. Mesela TextChanged olayına ayrı, KeyDown olayına ayrı, KeyUp olayına ayrı kod yazabiliriz.

Fakat nedense, textbox’tan metin kopyalarken/keserken veya textbox’a metin yapıştırırken fırlatılan bir olay yoktur. Çeşitli sebeplerle projelerimizde Kes-Kopyala-Yapıştır olaylarını fırlatan bir textbox’a ihtiyaç duyabiliriz.

Textbox kontrolüne özel event’ler eklemek için, yeni bir class oluşturup, Textbox class’ından türemesini sağlamalıyız.

public partial class GelismisTextBox : TextBox
{
}

Windows‘un sunduğu Kes-Kopyala-Yapıştır olaylarını GelismisTextbox class’ımızda yönetebilmek için WndProc() method’unu override etmemiz lazım.

private const int WM_CUT = 0x0300;
private const int WM_COPY = 0x0301;
private const int WM_PASTE = 0x0302;

protected override void WndProc(ref Message m)
{
	switch(m.Msg)
	{
		case WM_CUT:
			/// Kes komutu olayını fırlat
			break;
		case WM_COPY:
			/// Kopyala komutu olayını fırlat
			break;
		case WM_PASTE:
			/// Yapıştır komutu olayını fırlat
			break;
		default:
			base.WndProc(ref m);
			break;
	}
}

Şimdi yapmamız gereken, GelismisTextbox class’ımıza olayları fırlatacak kodu eklemek.

public class ClipboardEventArgs : EventArgs
{
	private string clipboardText;
	public string ClipboardText
	{
		get { return clipboardText; }
		set { clipboardText = value; }
	}

	public ClipboardEventArgs(string clipboardText)
	{
		this.clipboardText = clipboardText;
	}
}
public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);

public event ClipboardEventHandler CutText;
public event ClipboardEventHandler CopiedText;
public event ClipboardEventHandler PastedText;

Artık GelismisTextbox kontrolünü projemizde kullanabiliriz. GelismisTextbox kontrolünde yapılacak Kes-Kopyala-Yapıştır işlemleri esnasında fırlatılacak olaylara ilişkin kodlarda yazabiliriz. Örneğin;

private void txtOrnek_CutText(object sender, ClipboardEventArgs e)
{
	MessageBox.Show("Gelişmiş Textbox'tan kesilen : " + e.ClipboardText);
}
private void txtOrnek_CopiedText(object sender, ClipboardEventArgs e)
{
	MessageBox.Show("Gelişmiş Textbox'tan kopyalanan : " + e.ClipboardText);
}
private void txtOrnek_PastedText(object sender, ClipboardEventArgs e)
{
	MessageBox.Show("Gelişmiş Textbox'a yapıştırılan : " + e.ClipboardText);
}

GelismisTexbox class’ının kodu;

public partial class GelismisTextBox : TextBox
{
	private const int WM_CUT = 0x0300;
	private const int WM_COPY = 0x0301;
	private const int WM_PASTE = 0x0302;

	public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);

	public event ClipboardEventHandler CutText;
	public event ClipboardEventHandler CopiedText;
	public event ClipboardEventHandler PastedText;

	protected override void WndProc(ref Message m)
	{
		switch(m.Msg)
		{
			case WM_CUT:
				if (CutText != null)
					CutText(this, new ClipboardEventArgs(this.SelectedText));
				break;
			case WM_COPY:
				if (CopiedText != null)
					CopiedText(this, new ClipboardEventArgs(this.SelectedText));
				break;
			case WM_PASTE:
				if (PastedText != null)
					PastedText(this, new ClipboardEventArgs(Clipboard.GetText()));
				break;
			default:
				base.WndProc(ref m);
				break;
		}
	}
}

public class ClipboardEventArgs : EventArgs
{
	private string clipboardText;
	public string ClipboardText
	{
		get { return clipboardText; }
		set { clipboardText = value; }
	}

	public ClipboardEventArgs(string clipboardText)
	{
		this.clipboardText = clipboardText;
	}
}

C# ile Ping Uygulaması

Windows komut satırından çağırabileceğiniz ping komutu ile kendi bilgisayarınızdan, networkünüzde bulunan diğer bilgisayarlara Ping atabilirsiniz.

Bazı durumlarda uygulamamıza ping yeteneği eklememiz gerekebilir. (Sunuculara erişilemediği anı yakalayıp, ilgili birimleri uyarmak gibi) Bu yazımda C# ile ping uygulaması yazacağız.

Hemen ekran görüntüsü ile başlayalım;

İlk başlangıç noktamız, MSDN’de şu sayfadan bilgilerine erişebileceğiniz Ping class’ı olacak. Ping class’ı, framework içerisinde System.Net.NetworkInformation namespace’i içerisinde yeralır.

private void btnPing_Click(object sender, EventArgs e)
{
	Ping p = new Ping();
	Timer t = new Timer() { Interval=1000 };
	t.Start();
	t.Tick += delegate(object _s, EventArgs _e) {
		PingReply pr = p.Send(txtAdres.Text);
		txtSonuc.Text += string.Format("Sonuç: {0}, {1} -> {2} ms.{3}", pr.Status.ToString(), pr.Address.ToString(), pr.RoundtripTime.ToString(), Environment.NewLine);
	};
}

Ping butonunun Click olayında, Ping ve Timer class’larından birer örnek oluşturuyoruz. Timer nesnesinin Tick olayında, Ping nesnesinin Send() method’unu çağırıyoruz, dönen sonucu PingReply sınıfında bir değişkene atıyoruz ve txtSonuc Textbox‘ında gösteriyoruz.

Uygulamanın kaynak kodlarını buradan indirebilirsiniz.

Kelimenin son harfi ile başlayan kelime oyunu

Eminim hepimiz, kendi aramızda, “Kelimenin Son Harfi ile Başlayan Kelime Oyunu“nu oynamışızdır.

Oyunun kuralları basittir, iki “oyuncu” karşılıklı oturur, oyunculardan biri, bir kelime söyleyerek oyunu başlatır. Sonra oyuncular sırayla, diğerinin söylediği kelimenin son harfi ile başlayan başka bir kelime söylemek zorundadır. Söyleyecek kelime bulamayan oyuncu “oyunu” kaybeder.

Gelin bu basit oyunu C# ile yazalım. Hemen ekran görüntüsü vererek başlıyorum;

Oyunu, bir Oyuncu, bir Bilgisayar Oyuncusuna karşı oynayacak. İhtiyacımız olan ilk şey, Bilgisayar Oyuncusu’nun içinden kelime seçeceği sözlük. Sözlük oluşturmak için daha önce yazdığım Web Sayfasından Sözlük Oluşturma ve Dizi Karıştırma makalelerini birleştirip kullanacağız.

btnYeniOyun butonunun Click olayında, txtAdres kontrolüne yazılmış olan web sayfasındaki kelimeler bir listeye dolduruluyor, ayıklanıyor, karıştırılıyor ve lbKullanilabilecekKelimeler ListBox kontrolünde gösteriliyor.

public static class ExtensionManager
{
	private static Random r = new Random();

	public static List<T> ListeKaristir<T>(this List<T> Liste)
	{
		List<T> tmpList = Liste.GetRange(0, Liste.Count);
		List<T> arrReturn = new List<T>();

		while (tmpList.Count > 0)
		{
			int rastgele = r.Next(0, tmpList.Count);
			arrReturn.Add(tmpList[rastgele]);
			tmpList.RemoveAt(rastgele);
		}

		return arrReturn;
	}
}
private void btnYeniOyun_Click(object sender, EventArgs e)
{
	lbKullanilabilecekKelimeler.Items.Clear();
	lbKullanilabilecekKelimeler.BeginUpdate();

	WebRequest wr = WebRequest.Create(txtAdres.Text);
	WebResponse ws = wr.GetResponse();
	StreamReader sr = new StreamReader(ws.GetResponseStream(), Encoding.UTF8);
	string response = sr.ReadToEnd();
	sr.Close();
	ws.Close();

	List<string> arrKelime = new List<string>();

	Regex r = new Regex("<(.|\n)*?>");
	foreach (string satir in r.Replace(response, "").Split(" \t\r\n({[]}),.;:*-+/?<>&%'#@=\"\\_".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
		if (satir.Trim().Length > 5 && !arrKelime.Contains(satir.Trim()))
			arrKelime.Add(satir.Trim());

	lbKullanilabilecekKelimeler.Items.AddRange(arrKelime.ListeKaristir().ToArray());

	lbKullanilabilecekKelimeler.EndUpdate();

	txtYeniKelime.Clear();
	txtOyunTarihce.Clear();
}

Oyun, birinci oyuncunun txtYeniKelime kontrolüne yazdığı kelime ile başlıyor.

string OncekiKelimeninSonHarfi = string.Empty;
private void btnYeniKelime_Click(object sender, EventArgs e)
{
	if (txtYeniKelime.Text != "" && txtYeniKelime.Text.StartsWith(OncekiKelimeninSonHarfi))
	{
		string Kelime = txtYeniKelime.Text.Trim();
		txtOyunTarihce.Text = string.Format("(O): {0}{1}{2}", Kelime, Environment.NewLine, txtOyunTarihce.Text);
		txtYeniKelime.Clear();
		KelimeSec(Kelime);
		txtYeniKelime.Focus();
	}
}

Bilgisayar Oyuncusu Sözlük’ten kelimenin son harfi ile başlayan kelimelerden bir tanesini rastgele olarak seçiyor.

Kullandığı her kelimeyi lbKullanilabilecekKelimeler ListBox kontrolünden çıkartıp, lbKullanilmisKelimeler ListBox listesine ekliyor.

private void KelimeSec(string OncekiKelime)
{
	Random r = new Random();

	var Kelimeler = (from k in lbKullanilabilecekKelimeler.Items.OfType<string>() where k.StartsWith(OncekiKelime.Substring(OncekiKelime.Length - 1, 1)) select k).ToList<string>();

	if (Kelimeler.Count == 0)
	{
		MessageBox.Show(lbKullanilmisKelimeler.Items.Count + ". Kelimede Bilgisayar Oyuncusu oynayacak Kelime bulamadı!.", "Oyun Bitti!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
		return;
	}

	int Sira = r.Next(0, Kelimeler.Count);
	string Kelime = Kelimeler[Sira];
	OncekiKelimeninSonHarfi = Kelime.Substring(Kelime.Length - 1, 1);

	lbKullanilabilecekKelimeler.Items.Remove(Kelime);
	lbKullanilmisKelimeler.Items.Add(Kelime);

	txtOyunTarihce.Text = string.Format("(B): {0}{1}{2}", Kelime, Environment.NewLine, txtOyunTarihce.Text);
}

Oyun, Bilgisayar Oyuncusu’nun kelime bulamamasına kadar devam ediyor.

Oyunun kaynak kodlarını buradan indirebilirsiniz.

Bu kodda ne yanlış var? – 1

04 Ocak 2010 engin.polat 7 comments

Database’de şu scripti çalıştıralım;

CREATE TABLE T_PERSONEL
(
  ADSOYAD VARCHAR(50),
  DOGUM_TARIHI SMALLDATETIME
)

INSERT INTO T_PERSONEL VALUES ('Engin POLAT',  '1981-01-12')
INSERT INTO T_PERSONEL VALUES ('Emre ERKAN', '1979-03-14')
INSERT INTO T_PERSONEL VALUES ('Ozan ÇAĞLARGİL',  '1982-09-27')
INSERT INTO T_PERSONEL VALUES ('Fatih DURGUT',  '1978-06-23')
INSERT INTO T_PERSONEL VALUES ('Burhan İNEGÖL',  '1980-11-08')

Aşağıdaki stored procedure’i yazalım.

CREATE PROCEDURE PR_PERSONEL_LISTE
(
  @SIRALAMA INT
)
AS
BEGIN
  SELECT ADSOYAD, DOGUM_TARIHI FROM T_PERSONEL
  ORDER BY
    CASE @SIRALAMA
      WHEN 1 THEN DOGUM_TARIHI
      WHEN 2 THEN ADSOYAD
    END
END

Bu procedure’ü 1 parametresi vererek çalıştırıyoruz, ve beklediğimiz sonucu alamıyoruz.

Nerede hata yaptık? (İpucu; parametre olarak 2 vermeyi deneyin)

Yorumlarınızı bekliyorum…

Categories: Programlama, SQL Tags: , , , , , ,

C# ile isNumeric() fonksiyonu yazalım

VB.NET programcılarının kullanabildiği, ama C#‘ta bulunmayan isNumeric() fonksiyonunu kendimiz yazacağız;

public static class ExtensionManager
{
	public static bool isNumeric(this string value)
	{
		double oReturn = 0;
		return double.TryParse(value, out oReturn);
	}
}

Artık C# kodumuzun herhangi bir yerinde

string Deger = "5";
bool Rakamsal = isNumeric(Deger);

veya

string Deger = "5";
bool Rakamsal = Deger.isNumeric();

kullanabiliriz.

C# ile Dizi Bölümleme

Bilgeadam’da öğrencilerimden birinin sorduğu soru üzerine, bir dizinin, belli sayıda elemanlardan oluşan alt dizilere bölünmesi ile ilgili aşağıdaki uygulamayı yazdım.

Uygulama şöyle çalışıyor; rastgele kelimelerden oluşan bir dizimiz var, bu diziyi, n elemanlı alt dizilere bölmek istiyoruz.

Hemen kolları sıvayalım ve kod yazmaya başlayalım.

Öncelikle rastgele kelime oluşturma fonksiyonunu yazalım;

const string Harfler = "abcdefghijklmnopqrstuvwxyz";
Random r = new Random();

public string RastgeleKelimeUret(int HarfAdet)
{
	char[] arrReturn = new char[HarfAdet];

	Parallel.For(0, HarfAdet, iLoop => {
		arrReturn[iLoop] = Harfler[r.Next(0, Harfler.Length - 1)];
	});

	return new string(arrReturn);
}

Bu fonksiyonu C# ile Dizi Karıştırma yazımdan hatırlayacaksınız. Şimdi bu fonksiyonu kullanarak List<string> tipinde bir diziye 25 eleman dolduran kodumuzu yazalım;

List<string> BolunecekDizi = new List<string>();
Parallel.For(5, 25, iLoop => {
	BolunecekDizi.Add(RastgeleKelimeUret(iLoop));
});

Parallel For kullanarak Multi-Core ve Multi-Thread destekli kod yazdığımıza dikkat edelim. Bölümleme fonksiyonunu ExtensionMethod olarak yazacağız.

public static class ExtensionManager
{
	public static List<T>[] Bolumle<T>(this List<T> Dizi, int ParcaAdet)
	{
		if (Dizi == null)
			throw new Exception("Dizi boş olamaz..");

		if (ParcaAdet < 1)
			throw new Exception("Parça Adet 1'den küçük olamaz..");

		int DiziBoyu = (int)Math.Floor(Dizi.Count / (double)ParcaAdet) + 1;

		List<T>[] arrReturn = new List<T>[DiziBoyu];

		int Adim = 0;
		Parallel.For(0, Dizi.Count, iLoop => {
			if (iLoop % ParcaAdet == 0 && iLoop > 0)
				Adim += 1;

			if (arrReturn[Adim] == null)
				arrReturn[Adim] = new List<T>();

			arrReturn[Adim].Add(Dizi[iLoop]);
		});

		return arrReturn;
	}
}

Artık tek yapmamız gereken List<T> generic tipinde nesnelerde Bolumle() fonksiyonunu kullanmak olacak.

List<string>[] Bolumler = BolunecekDizi.Bolumle(3);

Uygulamanın kaynak kodlarını buradan indirebilirsiniz.