<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CETURK &#187; Yasin Sirkecili</title>
	<atom:link href="http://www.ceturk.com/etiket/yasin-sirkecili/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ceturk.com</link>
	<description>Türkiye&#039;nin Bilişim Platformu</description>
	<lastBuildDate>Wed, 08 Sep 2010 08:53:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>C# ile Soundex Algoritması(Bunu mu demek istediniz?)</title>
		<link>http://www.ceturk.com/programlama/c-ile-soundex-algoritmasibunu-mu-demek-istediniz.html</link>
		<comments>http://www.ceturk.com/programlama/c-ile-soundex-algoritmasibunu-mu-demek-istediniz.html#comments</comments>
		<pubDate>Sun, 01 Nov 2009 13:08:59 +0000</pubDate>
		<dc:creator>Olcay KÜK</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[bunu mu demek istediniz]]></category>
		<category><![CDATA[C# ile soundex]]></category>
		<category><![CDATA[soundex]]></category>
		<category><![CDATA[soundex algoritması]]></category>
		<category><![CDATA[Yasin Sirkecili]]></category>

		<guid isPermaLink="false">http://www.ceturk.com/?p=3467</guid>
		<description><![CDATA[Herkese merhabalar bu makalemizde Fonetik algoritmalar içerisinde önemli bir yer tutan Soundex algoritmasını inceleyeceğiz. İnsanoğlunun uzun yıllar boyunca süren zeka gelişimi evrelerine baktığımızda, her yeni dönemin, dünyayı tanıma evrelerinin getirdiği yeni bilgi akışları ve bu bilgilerin kullanımlarına dair uygulanabilirlikleri tanımladığını görebiliriz. 18. Yüzyıldan bu yana insanoğlu matematik ve fizik alanlarında birçok yeni buluşlar yapmış ve [...]]]></description>
			<content:encoded><![CDATA[<p>Herkese merhabalar bu makalemizde Fonetik algoritmalar içerisinde önemli bir yer tutan Soundex algoritmasını inceleyeceğiz. İnsanoğlunun uzun yıllar boyunca süren zeka gelişimi evrelerine baktığımızda, her yeni dönemin, dünyayı tanıma evrelerinin getirdiği yeni bilgi akışları ve bu bilgilerin kullanımlarına dair uygulanabilirlikleri tanımladığını görebiliriz. 18. Yüzyıldan bu yana insanoğlu matematik ve fizik alanlarında birçok yeni buluşlar yapmış ve bu buluşların eğitim öğretim hayatına aktarılmasıyla insan zihninin hiç olmadığı kadar zorlanarak geliştirilebilmesine olanak sağlamıştır.<span id="more-3467"></span></p>
<p>Yarım asır geriye döndüğümüzde bile daha az bilgi havuzu içerisinde yaşayan toplumların hafızalarını incelediğimizde karmaşa içerisinde olmayan net ve temiz bilginin hafızaya olan etkilerinin aynı doğrultuda olduğunu görebiliriz. Ancak günümüze geldiğimizde tüm dünyanın bir metropol trafiği kadar hızlı ve karmaşık bir bilgi çöplüğü haline geldiğini söylemek sanırım çok yanlış olmaz. Karmaşık ve aşırı bilginin/verinin çoğu zaman hafızalarımızda hatırlanması zor yada kısmi hatırlama süreçlerine neden olduğunu söyleyebiliriz.</p>
<p>Veri depolama ve sorgulama tekniklerinin bilgisayar ortamında geliştirilmesinden bu yana insan hayatının derin ölçülerde kolaylaştırıldığı aşikar. Artık hep hayal gözüyle baktığımız algılama ve öğrenme yeteneğine sahip yapay zeka uygulamalarından söz edebiliyoruz.</p>
<p>Örneğin text türünde verileri ararken aradığımız kelimenin bir kısmını girerek sonuca ulaşmamız yada doğru hatırlayamadığımız bir kelimenin bir kısmını girerek benzer sonuçları bulabilmemiz oldukça kolay. İşte Soundex algoritmasının uygulamalarımıza sağladığı faydalardan biride tam olarak bu noktada karşımıza çıkıyor.Bir makale için bu kadar uzun bir giriş yaparak buraya kadar okumanıza sebep olmam hoşunuza gitmemiş olabilir. Ancak fonetik algoritmaların değerinin sadece yanlış girilen veya benzer veriler ile karşılaştırma yapmaktan öte hafızamızda tam olarak kalmayan verileri bulmamızı sağladığı gerçeğini de göstermek istedim.</p>
<p>Şimdi nedir Soundex algoritması nasıl çalışır ona bakalım;</p>
<p>Soundex algoritması gelişmiş birçok veritabanın içeriğinde hazır bir fonksiyon olarak gelen telaffuz aşamasında birbirine ses benzerliği olan kelimeleri bulmamızı sağlayan basit bir algoritmadır. Robert Russell ve Margaret Odell tarafından geliştirilmiştir. Çalışma mantığı tek bir kelime için 5 temel aşamadan oluşur. Bu aşamaları şöyle sıralayabiliriz;</p>
<p>1-) Kelimenin ilk harfi olduğu gibi kalır.<br />
2-) İlk harf haricindeki harfler arasından A, E , H , I, O , U, W, Y harfleri çıkartılır.<br />
3-) Yine ilk harf haricindeki harfler arasından aşağıdaki listeye uygun olarak harfler numaralara çevrilir.</p>
<p><img class="alignnone size-full wp-image-3475" title="Adsız" src="http://www.ceturk.com/images/Adsız.jpg" alt="Adsız" width="302" height="122" /></p>
<p>4-) Yan yana olan aynı harf yada aynı numara kümesine dahil olabilecek harfler tekile indirilir.<br />
5-) Bu şekilde oluşturulan metin 4 haneli olana kadar eksik karakterler 0 ile tamamlanır.</p>
<p>Soundex algoritması MSSQL , Oracle, MySQL gibi birçok veritabanında hazır olarak gelse de Veritabanı kullanmadığımız yada verilerimizin disconnected layer olarak bulunduğu durumlarda veya veritabanı olarak kullanılan dosyanın (Örn; Excel) soundex algoritmasını içermediği durumlarda mevcut veriler üzerinde bu algoritmayı nasıl kullanabileceğimizi inceleyelim,</p>
<p>İlk olarak Soundex adında bir fonksiyonu Extension Method olarak kullanabilmek adına static bir class yaratıyoruz ve içerisinde Soundex adında string tipindeki fonksiyonumuzu yazıyoruz.</p>
<p><img class="alignnone size-full wp-image-3468" title="soundex1" src="http://www.ceturk.com/images/soundex1.jpg" alt="soundex1" width="323" height="209" /></p>
<p>İlk olarak Soundex adında bir fonksiyonu Extension Method olarak kullanabilmek adına static bir class yaratıyoruz ve içerisinde Soundex adında string tipindeki fonksiyonumuzu yazıyoruz.</p>
<p>Kodlarımıza bakacak olursak;</p>
<div>
<pre class="brush:csharp">static class ExtensionMethods
{
public static string Soundex(this string exp)
{
string deger = String.Empty;
if (exp.Length &gt; 1)
{
deger = exp.Substring(0, 1);
exp = exp.Substring(1, exp.Length - 1);

exp = exp.Replace("Ğ", "G");
exp = exp.Replace("Ü", "U");
exp = exp.Replace("Ş", "S");
exp = exp.Replace("Ö", "O");
exp = exp.Replace("İ", "I");
exp = exp.Replace("Ç", "C");

exp = exp.Replace("A", "");
exp = exp.Replace("E", "");
exp = exp.Replace("H", "");
exp = exp.Replace("I", "");
exp = exp.Replace("O", "");
exp = exp.Replace("U", "");
exp = exp.Replace("W", "");
exp = exp.Replace("Y", "");

string karakter = "";
string o_karakter = "";

for (int i = 0; i &lt; exp.Length; i++)
{
int code = new int();

karakter = exp[i].ToString();
if ("BFVP".Contains(karakter))
{
code = 1;
}
else if ("CGJKQSXZ".Contains(karakter))
{
code = 2;
}
else if ("DT".Contains(karakter))
{
code = 3;
}
else if ("L".Contains(karakter))
{
code = 4;
}
else if ("MN".Contains(karakter))
{
code = 5;
}
else if ("R".Contains(karakter))
{
code = 6;
}
if (karakter != o_karakter)
{
if (deger.Substring((deger.Length - 1), 1) != code.ToString())
{
deger += code.ToString();
}
}
if (deger.Length == 4)
{
break;
}
if (karakter != "")
{
o_karakter = karakter;
}
}
int uzunluk = deger.Length;
for (int j = 0; j &lt; (4 - uzunluk); j++)
{
deger += "0";
}
}
return deger;
}
}</pre>
</div>
<p>İlk olarak “deger” adında yeni bir string değişken yaratıyoruz bu değişkene bizim fonksiyondan geriye değer döndereceğimiz değişken diyebiliriz.</p>
<p>Fonksiyona ait string tipindeki parametremiz olan exp değişkenin karakter uzunluğu eğer 1 karakterden fazla ise işlem görmesini sağlıyoruz.</p>
<div>
<pre class="brush:csharp">deger = exp.Substring(0, 1);
exp = exp.Substring(1, exp.Length - 1);</pre>
</div>
<p>Yeni oluşacak katarımızda 1. Madde de olduğu üzere metnin ilk karakterini deger stringine aktarıyoruz ve exp stringi içerisinden bu karakteri çıkartıyoruz.</p>
<div>
<pre class="brush:csharp">exp = exp.Replace("Ğ", "G");
exp = exp.Replace("Ü", "U");
exp = exp.Replace("Ş", "S");
exp = exp.Replace("Ö", "O");
exp = exp.Replace("İ", "I");
exp = exp.Replace("Ç", "C");</pre>
</div>
<p>Soundex algoritmasına ait bu makalede anlattığımız dizilim İngilizce için geçerli olduğunu belirtmek isterim. Ancak biz bu makalemizde Türkçe harfleri İngilizce alfabesinde varolan şekilsel benzerlikleri ile değiştiriyoruz. Aslında bu anlamda daha ciddi bir çalışma yapılarak telaffuz hususundaki harf benzerliklerini daha net belirlemek için ilgili kurumların bilimsel çalışmalarından yararlanılabilir.</p>
<p>Algoritmamızın devam eden kısmında 2. Madde de olduğu üzere;</p>
<div>
<pre class="brush:csharp">exp = exp.Replace("A", "");
exp = exp.Replace("E", "");
exp = exp.Replace("H", "");
exp = exp.Replace("I", "");
exp = exp.Replace("O", "");
exp = exp.Replace("U", "");
exp = exp.Replace("W", "");
exp = exp.Replace("Y", "");</pre>
</div>
<p>A,E,H,I,O,U,W,Y harflerini exp stringimizden çıkartıyoruz.<br />
3. maddemizde belirtilen harf kümelerine göre sayısal değerler vermek amacıyla for döngüsüne başlamadan önce</p>
<div>
<pre class="brush:csharp">string karakter = "";
string o_karakter = "";</pre>
</div>
<p>şeklinde 2 string tipli değişken yaratıyoruz bu değişkenlerden “karakter” o an işlem yaptığımız karakter değerini alırken “o_karakter”(önceki karakter) döngü sonunda son aktarılan karakteri bir sonraki değer artışında saklamak için tutacak.</p>
<div>
<pre class="brush:csharp">for (int i = 0; i &lt; exp.Length; i++)
{
int code = new int();

karakter = exp[i].ToString();</pre>
</div>
<p>exp değişkeni içerisindeki 1. Karakteri deger stringe aktardığımız için kalan karakterler arasında 0. Karakterden başlayarak her karakterin “karakter” stringine aktarılmasını sağlıyor ve aşağıdaki if bloguyla devam ederek ilgili karaktere karşılık gelen sayısal değeri buluyoruz.</p>
<div>
<pre class="brush:csharp">if ("BFVP".Contains(karakter))
{
code = 1;
}
else if ("CGJKQSXZ".Contains(karakter))
{
code = 2;
}
else if ("DT".Contains(karakter))
{
code = 3;
}
else if ("L".Contains(karakter))
{
code = 4;
}
else if ("MN".Contains(karakter))
{
code = 5;
}
else if ("R".Contains(karakter))
{
code = 6;
}</pre>
</div>
<p>For döngümüz içerisinde son olarak 4. Maddede belirttiğim üzere yan yana aynı harf yada aynı sayısal değere sahip olabilecek harfleri tekil hale indirgeyeceğiz.</p>
<div>
<pre class="brush:csharp">if (karakter != o_karakter)
{
if (deger.Substring((deger.Length - 1), 1) != code.ToString())
{
deger += code.ToString();
}
}
if (deger.Length == 4)
{
break;
}
if (karakter != "")
{
o_karakter = karakter;
}
}</pre>
</div>
<p>Şimdi buraya kadar yaptıklarımızı kısaca test etmek için sayfaya bir adet textbox,label ve buton ekliyorum. Butona tıklandığında textbox içerisindeki ifadenin soundex methodunu kullanarak yeni oluşturduğu stringi labelin text propertysine aktaracağız.</p>
<div>
<pre class="brush:csharp">protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = TextBox1.Text.Trim().ToUpper().Soundex();
}</pre>
</div>
<p><img class="alignnone size-full wp-image-3469" title="soundex2" src="http://www.ceturk.com/images/soundex2.jpg" alt="soundex2" width="232" height="67" /></p>
<p>Resimde de gördüğünüz üzere soundex fonksiyonundan geriye dönen değer Y250 olarak Label nesnesine aktarıldı.<br />
Textbox içerisinde yazdığımız ifadeye göre algoritmayı karşılaştıracak olursak fonksiyonumuzun çalışmasını şöyle izah edebiliriz.</p>
<p>1-) &#8220;Y&#8221; karakterini alır ve ifadeden çıkartır.<br />
2-) ”İ” karakterini “I” ya çeviriyor sonra &#8220;A&#8221; ve &#8220;I&#8221; karakterlerini ifade içerisinden çıkartıyor.(Buraya kadar yaptığımız işlemlerle ifademizde artık SN karakterleri kalır)<br />
3-) &#8220;S&#8221; karakterine karşılık gelen “2” ile &#8220;N&#8221; karakterine karşılık gelen “5” değerlerini yeni stringimize aktarır.<br />
4-) Yeni oluşan string değerimiz for döngüsü sonunda Y25 halinde bulunduğundan ve ifade içerisinde başka karakter olmamasından ötürü yeni stringimizi 4 karakterli yapabilmek amacıyla sonunda bir tane “0” ekliyor.</p>
<p>Böylelikle algoritmamızın soundex algoritmasının açıklamasında belirttiğimiz maddelere göre doğru çalıştığını söyleyebiliriz.<br />
Şimdi mevcut fonksiyonumuzu kullanmak amacıyla Access veritabanında varolan değerler içerisinde yanlış yazdığımız bir karakteri bulmamızı sağlayacak küçük bir aplikasyon hazırlayabiliriz.</p>
<div>
<pre class="brush:csharp">protected void Button1_Click(object sender, EventArgs e)
{
OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OleDb.12.0;Data Source=D:\postakodlari.mdb");
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select TOP 1 ILADI from pkod where ILADI=@ILADI";
cmd.Parameters.Add(new OleDbParameter("@ILADI",TextBox1.Text.Trim()));
conn.Open();
if (cmd.ExecuteScalar() == null)
{
OleDbDataAdapter adapter = new OleDbDataAdapter("select distinct ILADI from pkod order by ILADI", conn);

DataTable dtable = new DataTable();
adapter.Fill(dtable);
conn.Close();
string metin = TextBox1.Text.Trim().ToUpper().Soundex();
System.Collections.ArrayList alist = new ArrayList();
for (int i = 0; i &lt; dtable.Rows.Count; i++)
{
if (dtable.Rows[i]["ILADI"].ToString().Soundex() == metin)
{
alist.Add(dtable.Rows[i]["ILADI"].ToString());
}
}
if (alist.Count != 0)
{
Label1.Text = "Bunumu demek istediniz?: ";
for (int i = 0; i &lt; alist.Count; i++)
{

Label1.Text += alist[i].ToString();
if (i != (alist.Count - 1))
{
Label1.Text += ",";
}
}
}
else
{
Label1.Text = "aradığınız kritere uygun bir sonuç bulunamadı";
}
conn.Close();
}
else
{

Label1.Text = "sorgulanan veri mevcuttur: " + cmd.ExecuteScalar().ToString();
conn.Close();
}
}</pre>
</div>
<p>Aplikasyonumuzu kısaca şöyle açıklayabiliriz;</p>
<p>Postakodlari.mdb veritabanı içerisinde bulunan pkod tablosundaki ILADI kolonu içerisinde arama yapacağız eğer textbox içerisine girilen veri mevcutsa label’ın text propertysine sonucun varolduğuna dair</p>
<p><img class="alignnone size-full wp-image-3470" title="soundex3" src="http://www.ceturk.com/images/soundex3.jpg" alt="soundex3" width="252" height="61" /></p>
<p>“Sorgulanan veri mevcuttur: “</p>
<p>şeklinde bir metin aktarıyoruz.<br />
Eğer aranılan veri yoksa ve kolondaki değerlerin soundex fonksiyonu sonucunda aranılan veriye benzer veriler ile karşılaşıyorsak bu verilerin alist adındaki ArrayList’imize aktarılmasını sağlıyoruz.</p>
<p>İşlem sonucunda alist adındaki ArrayList’imizin Count değeri sıfırdan farklı ise label’ın text property’sine bu değerleri aralarına virgül koyarak yazdırıyoruz.</p>
<div>
<pre class="brush:csharp">if (alist.Count != 0)
{
Label1.Text = "Bunu mu demek istediniz?: ";
for (int i = 0; i &lt; alist.Count; i++)
{

Label1.Text += alist[i].ToString();
if (i != (alist.Count - 1))
{
Label1.Text += ",";
}
}
}</pre>
</div>
<p><img class="alignnone size-full wp-image-3471" title="soundex4" src="http://www.ceturk.com/images/soundex4.jpg" alt="soundex4" width="252" height="61" /><img class="alignnone size-full wp-image-3472" title="soundex5" src="http://www.ceturk.com/images/soundex5.jpg" alt="soundex5" width="252" height="61" /></p>
<p>Eğer alist in count değeri sıfır ise;</p>
<div>
<pre class="brush:csharp">else
{
Label1.Text = "aradığınız kritere uygun bir sonuç bulunamadı";
}</pre>
</div>
<p>Şeklindeki değerimizi aktarıyoruz.</p>
<p><img class="alignnone size-full wp-image-3473" title="soundex6" src="http://www.ceturk.com/images/soundex6.jpg" alt="soundex6" width="282" height="55" /></p>
<p>Hepsi bu kadar…</p>
<p>Şunu hatırlatmak isterim. Google’ın “Bunu mu demek istediniz?” şeklinde kullanıcılara gösterdiği sonuçlar Ori Allon tarafından geliştirilen Orion algoritması çerçevesinde ki veriler ile karşılaştırılmaktadır. Bu sebeple ürettiğiniz sonuçlarda google ile birebir aynı neticelere erişemeyebilirsiniz. Ancak bu algoritmayı kendi projelerinizde kullanabilirsiniz.</p>
<p>Tüm yazılımcı arkadaşlara mutlu günler dilerim…</p>
<p>İyi çalışmalar,<br />
<strong>Yasin SİRKECİLİ</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ceturk.com/programlama/c-ile-soundex-algoritmasibunu-mu-demek-istediniz.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C# ile OCR(Optical Character Recognition) &#8211; VSTO</title>
		<link>http://www.ceturk.com/programlama/c-sharp-ile-ocroptical-character-recognition-vsto.html</link>
		<comments>http://www.ceturk.com/programlama/c-sharp-ile-ocroptical-character-recognition-vsto.html#comments</comments>
		<pubDate>Sun, 01 Nov 2009 01:43:00 +0000</pubDate>
		<dc:creator>Olcay KÜK</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[C# ile OCR]]></category>
		<category><![CDATA[OCR]]></category>
		<category><![CDATA[Optical Character Recognition]]></category>
		<category><![CDATA[VSTO]]></category>
		<category><![CDATA[Yasin Sirke]]></category>
		<category><![CDATA[Yasin Sirkecili]]></category>

		<guid isPermaLink="false">http://www.ceturk.com/?p=3442</guid>
		<description><![CDATA[Herkese merhabalar;
Bugünkü konumuz printer, daktilo, fotokopi vb. kağıt halindeki çıktılardan tutunda plaka tanıma sistemlerine kadar uzanan insan hayatını kolaylaştıran en sevdiğim yapay zeka uygulamalarından olan OCR(Optical Character Recognition) uygulamasının C# ile nasıl yapılacağına basitce bakacağız. Amacımız JPG dosyasındaki text verileri tanımlayıp *.txt dosyasına aktaracak bir OCR(Optical Character Recognition) uygulaması gerçekleştirmek.

İlk olarak projemize COM objesi olan [...]]]></description>
			<content:encoded><![CDATA[<p>Herkese merhabalar;</p>
<p>Bugünkü konumuz printer, daktilo, fotokopi vb. kağıt halindeki çıktılardan tutunda plaka tanıma sistemlerine kadar uzanan insan hayatını kolaylaştıran en sevdiğim yapay zeka uygulamalarından olan OCR(Optical Character Recognition) uygulamasının C# ile nasıl yapılacağına basitce bakacağız. Amacımız JPG dosyasındaki text verileri tanımlayıp *.txt dosyasına aktaracak bir OCR(Optical Character Recognition) uygulaması gerçekleştirmek.<br />
<span id="more-3442"></span><br />
İlk olarak projemize COM objesi olan Microsoft Office Document Imaging 12.0 Type Library referansını ekliyoruz. bu referans eklendiğinde MODI adında bir namespace&#8217;in kullanılabilir olduğunu göreceksiniz. Bu API Office 2003 ile birlikte geldiğinden Office 2003 veya üstü versiyonlarla kullanabilirsiniz. Ben projemi bir ASP.NET Web uygulaması olarak gerçekleştirdim siz isterseniz Windows Application kullanarak taranan veriyi richtextbox&#8217;a aktarabilirsiniz.</p>
<p>uygulamamızın xhtml görünümü şöyledir;</p>
<div>
<pre class="brush:csharp">
<form id="form1">
</form>
</pre>
</div>
<p>Sadece bir FileUpload ve button kontrolü kullandığımız projenin icrası şu yönde olacaktır; Resim seçildikten sonra eğer jpg formatındaysa resmin adı değiştirilip jpgs diye bir klasöre aktarılacak daha sonra burda OCR işlemi gerçekleştirilecek.</p>
<div>
<pre class="brush:csharp">if(FileUpload1.HasFile)
{
stringuzanti = System.IO.Path.GetExtension(FileUpload1.FileName.ToLower().Replace("", "i"));
if(uzanti == ".jpg")
{
stringdosyaadi = DateTime.Now.ToString().Replace(".", "").Replace(":", "").Replace("/", "").Replace("-", "").Replace(" ", "");
dosyaadi += uzanti;
FileUpload1.SaveAs(HttpContext.Current.Server.MapPath("~/jpgs/"+ dosyaadi));
System.IO.FileStreamfstream;
System.IO.StreamWriterswriter;
try
{
MODI.Documentmdoc = newMODI.Document();
mdoc.Create(HttpContext.Current.Server.MapPath("~/jpgs/"+ dosyaadi));
mdoc.OCR(MODI.MiLANGUAGES.miLANG_TURKISH, true, true);
MODI.Imagemimg = mdoc.Images[0] asMODI.Image;
fstream = newSystem.IO.FileStream(HttpContext.Current.Server.MapPath("~/yasin.txt"), System.IO.FileMode.OpenOrCreate);
swriter = newSystem.IO.StreamWriter(fstream);
swriter.Write(mimg.Layout.Text);
swriter.Close();
fstream.Close();
}
catch
{
ScriptManager.RegisterStartupScript(Page, typeof(string), Guid.NewGuid().ToString(), "alert('Hata olutu');", true);
}
}
else
{
ScriptManager.RegisterStartupScript(Page, typeof(string), Guid.NewGuid().ToString(), "alert('.jpg formatında bir dosya seçiniz.');", true);
}
}
else
{
ScriptManager.RegisterStartupScript(Page, typeof(string), Guid.NewGuid().ToString(), "alert('Dosya seçmediniz.');", true);
}</pre>
</div>
<p>Kodlarımızı açıklayacak olursak;</p>
<p>İlk olarak System.IO.Path sınıfı altındaki getextension fonksiyonundan faydalanarak aktarılan dosyanın .jpg uzantısına sahip olup olmadığını kontrol ediyoruz. Daha sonra bu dosyayı jpgs adında oluşturduğumuz klasöre aktarıyoruz.(Dosya adının çakışmasını engellemek için tarihe göre isim değiştiriyoruz) Sonrasında Jpg file içerisinde taranan karakterleri *.txt dosyasına aktarmamızı sağlayacak olan filestream ve streamwriter classlarından birer instance yaratıyoruz.</p>
<p>MODI.Documentmdoc = newMODI.Document();</p>
<p>ile mdoc adında MODI.Document classından OCR işleminde kullanacağımız yeni bir instance türettik.</p>
<p>mdoc nesnesinin Create fonksiyonunu kullanarak parametre olarak taranacak jpg dosyasının yolunu belirtiyoruz.</p>
<p>mdoc nesnesinin sahip olduğu en önemli fonksiyonumuz olan OCR fonksiyonuna gönderdiğimiz parametrelerle tarama işleminin sonuçlanmasını sağlıyoruz. Burdaki parametrelere ait açıklamalar şöyledir;</p>
<p>1 -) <strong>LangId </strong>: MODI.MiLANGUAGES enum değişkeninde tanımlanan karakter setlerinden size uygun olanı seçmenizi sağlar.<br />
2- ) <strong>OCROrientImage </strong>: Sayfanın yatay veya dikey olup olmadığının API tarafından algılanmasını sağlayan boolean tipli bir değerdir.<br />
3- ) <strong>OCRStraightenImage </strong>:  API tarafından image üzerindeki karakter tanımayı engelleyici eğimlerin otomatik olarak düzenmesine karar veren  boolean tipli değişkendir.</p>
<p>daha sonra MODI.Image tipinde oluşturduğumuz mimg nesnemize mdoc içerisindeki resimlerden istediğimizi aktarıyoruz.(Biz tek bir resim üzerinde işlem yaptığımızdan 0 index&#8217;ine sahip resmi aktardık)</p>
<p>bu işlemleri tamamladıktan sonra taranan ve karakter haline çevrilen verileri yasin.txt dosyasına yazarak filestream, streamwriter nesnelerinden türettiğimiz instance&#8217;ları Close(); methoduyla sonlandırarak jpg file içerisindeki karakterlerin yasin.txt dosyasına aktardığını gözlemleyebiliriz.</p>
<p>OCR işlemlerinin en basit hali bu şekilde uygulanabilir, dilerseniz siz daha detaylı OCR uygulamaları geliştirebilirsiniz.</p>
<p>Tüm yazılımcı arkadaşlara mutlu günler dilerim&#8230;</p>
<p>iyi çalışmalar,<br />
<strong>Yasin SİRKECİLİ</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ceturk.com/programlama/c-sharp-ile-ocroptical-character-recognition-vsto.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# ile Drag &amp; Drop</title>
		<link>http://www.ceturk.com/programlama/csharp-ile-drag-drop.html</link>
		<comments>http://www.ceturk.com/programlama/csharp-ile-drag-drop.html#comments</comments>
		<pubDate>Mon, 22 Jun 2009 00:21:09 +0000</pubDate>
		<dc:creator>yido</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[C# ile Drag & Drop]]></category>
		<category><![CDATA[Yasin Sirkecili]]></category>

		<guid isPermaLink="false">http://www.ceturk.com/?p=1358</guid>
		<description><![CDATA[Yeni bir makaleden herkese merhabalar,
Bu makalemizde çok sık sorulan ve bence kullanıcının arayüze alışması, Düşük bilgisayar bilgisi olan kullanıcıların arayüze kısa sürede adapte olabilmesi açısından çok önemli bir nokta teşkil eden Drag &#38; Drop konusunu çok fazla karıştırmadan basitçe C# ile ele alacağız.
Unutmayın ki bir yazılım geliştirici olarak yazılımınıza odaklanmak haricinde birkaç adım sonrasını da [...]]]></description>
			<content:encoded><![CDATA[<p>Yeni bir makaleden herkese merhabalar,</p>
<p>Bu makalemizde çok sık sorulan ve bence kullanıcının arayüze alışması, Düşük bilgisayar bilgisi olan kullanıcıların arayüze kısa sürede adapte olabilmesi açısından çok önemli bir nokta teşkil eden<strong> Drag &amp; Drop</strong> konusunu çok fazla karıştırmadan basitçe <strong>C#</strong> ile ele alacağız.</p>
<p>Unutmayın ki bir yazılım geliştirici olarak yazılımınıza odaklanmak haricinde birkaç adım sonrasını da gözlemlemek zorundasınız. Bunlara tasviri örnekler vermek gerekirse ürettiğiniz bir yazılımın üretim süreci sonunda karşılaşacaklarınızı önceden belirlemeli ve yazılımınızı bu değişken durumlara uyarlı hale getirmeli hatta uyarlı şekilde geliştirmelisiniz. Bu değişken noktalardan biride yazılımın kullanıcı bazlı eğitim sürecidir. Her ne kadar siz yazılımınızı üretirken çok fazla gözünüze gözükmese de büyük çaplı bir uygulama için binlerce dolar eğitim masrafının harcandığını ve eğitim süreci içerisinde sizin uygulamanıza rakip birçok yazılımın piyasaya çıktığını ve aynı zamanda bu rakip yazılımlar sizin programınızdan çok daha beceriksiz olsa bile  kullanıcının kullanım kolaylığı nedeniyle bu rakip yazılımları tercih edebilme olasılığı her zaman mevcuttur.</p>
<p>Bu konuda kişisel bir örnek vermek isterim&#8230; Cep telefonu olarak benim tercihim hep X&#8217;den yana olmuştur ve bence diğer telefonlara nazaran çok daha komplike bir yapıya, çok daha işlevsel özelliklere sahip bir telefon olmuştur benim için. Ancak Türkiye&#8217;de ve dünyada bu konuda pazarın çoğunluğuna sahip firmanın Y olduğunu görmekteyiz. 10 yıl öncesine dönecek olursak. Cep telefonuyla ilk tanışmalarımızda insanların tercihi hep Y&#8217;den yanaydı bunun sebebi o günlerden bu yana çok açıktı. &#8220;Kullanım kolaylığı&#8221;&#8230;</p>
<p>Sanırım basit bir konu için çok fazla konuştuk. Ama bu makalede anlatacaklarımın önemsiz olarak gözlemlesek de ne kadar önemli olduğuna dikkatinizi çekmek istedim.</p>
<p><em><strong>Artık başlayalım;</strong></em></p>
<p><strong>Drag &amp; Drop</strong> yani türkçesiyle<strong> Sürükle ve Bırak</strong> biraz açacak olursak bir nesnenin içindeki objeyi alıp içeriğine uygun başka bir nesneye taşımak veya kopyasını oluşturmak olarak özetleyebiliriz.</p>
<p>Drag &amp; Drop olayının esasında kısmen basit bir algoritmik yapısı olduğunu söyleyebiliriz. Bu olayı şematik olarak yansıtmak isterim.</p>
<p><strong>(a)</strong> Obje seçilir ve sürüklenmeye hazırlanır &gt;<strong> (b) </strong>İçeriği aktarılacak olan kontrole yöneltilir &gt; <strong>(c)</strong> Seçili nesne aktarılmak istenen kontrolün üzerine bırakılır.</p>
<p>Bu basit şematik gösterimde a,b,c olarak nitelendirdiğim şeylerin hepsi bir olay ve bir objenin taşınması bu olayların zorunlu olarak gerçekleşmesi ve bu olayların oluştuğu andaki izinlerin kontrolleri ile meydana gelir.</p>
<p>Şimdi bu şematik anlatımımızı programatik öğelere döküp açıklamaya çalışayim.</p>
<p>Öncelikle bu makalede yapacağımız örneği biraz açıklayim. Formumuza yerleştirdiğimiz iki adet listbox kontolündeki objelerden birini alıp diğerine taşıyacağız. Başta da belirttiğim gibi konuyu basitçe ele alıyorum ancak Drag &amp; Drop olayının en kullanışlı yöntemlerinden birinin Database üzerinde işlev gerçekleştirmek olduğunu unutmayın.</p>
<p>Örneğimizin görsel görüntüsü bu şekilde&#8230; Şimdi biz listBox1 kontrolündeki bir objeyi listBox2 ye sürükeyip bırakarak listBox2 içine aktarılmasını sağlayacağız. Yani hikaye bazında anlatmamız gerekirse &#8220;Tüm Programcılar&#8221;ı listBox1 de görüntüleyip &#8220;C# Kullananlar&#8221; ı listBox2&#8242;ye sürükleyerek ayrıştıracağız.</p>
<p><img class="aligncenter size-full wp-image-1359" src="http://www.ceturk.com/images/draganddrop1.gif" alt="draganddrop1" width="380" height="322" /><br />
ilk olarak listBox1 deki bir Item&#8217;ı seçmek için listBox1 in MouseDown özelliğinden faydalanacağız.</p>
<pre class="brush:csharp">private void listBox1_MouseDown(object sender, MouseEventArgs e)
{

Point snoktalar = new Point(e.X, e.Y);
int item_indis = listBox1.IndexFromPoint(snoktalar);

if (item_indis == -1)
{
MessageBox.Show("Boş bir alana tıkladınız. Boş alanda drag &amp; drop gerçekleştiremezsiniz.");
return;
}

if (e.Button == MouseButtons.Left) {
listBox1.DoDragDrop(listBox1.Items[item_indis], DragDropEffects.All);

}</pre>
<p>Şimdi bu kodlarımızı biraz açıklayalım&#8230; Öncelikle taşıma yönümüz listBox1 den listBox2&#8242; ye doğru olduğu için. Taşınacak Objeye listBox1 içeriğinde tıklanacağından listBox1&#8242;imizin MouseDown eventine tıklama anında ne yapabileceğini belirtiyoruz.</p>
<p>İlk olarak Point sınıfından bir nesne türeterek listBox içinde tıkladığımız noktanın koordinat bilgilerini alıyoruz. Daha sonra listBox1 kontrolümüzün IndexFromPoint methodundan faydalanarak bu koordinatlarda hangi objenin varolduğunu indisine bakarak integer tipli item_indis değişkenimize aktarıyoruz.</p>
<p>Daha sonra kullanıcının listBox1 içerisinde Item içermeyen boş bir alana tıkladığını düşünerek kodlarımızın bu noktada hata vermemesini sağlamak için.</p>
<pre class="brush:csharp">if (item_indis == -1)
{
MessageBox.Show("Boş bir alana tıkladınız. Boş alanda drag &amp; drop gerçekleştiremezsiniz.");
return;
}</pre>
<p>satırlarını ekliyoruz. Eğer kullanıcı listBox1 içerisinde Item içermeyen bir alana tıkladı ise Bu durumda IndexFromPoint methodu bize &#8220;-1&#8243; değerini dönderecektir. Bizde böyle bir durum oluştuğunda kullanıcıya bilgi verip kodlarımızın o noktada durmasını sağlıyoruz.</p>
<p>Daha sonra kontrol üzerine mouse ile tıklamanın mouse&#8217;un hangi tuşu ile gerçekleştiğini inceliyor ve eğer sol tuş ile tıklanmış ise DoDragDrop methodu ile ilgili kontrolün ilgili Item&#8217;nin taşıma işlemine başlamasını sağlıyoruz.  DragDropEffects parametresine verdiğimiz All değeri ile de bu Item&#8217;in nasıl taşınabileceğini belirtiyoruz.</p>
<p>listBox1 ile işimiz bitti diyebiliriz. Objemizi seçtik ve taşımaya hazır konuma getirdik artık bu seçili objemizin listBox2 ye sürüklenip bırakılması ve bırakıldığı anda listBox2 içerisine aktarılmasını sağlayacağız. Bunun için listBox2 kontrolümüzün içerisine bir obje bırakılabilir olduğuna dair iznini vermemiz gerekir. Bu sebeple listBox2 nin AllowDrop özelliğini true yapıyoruz.</p>
<p><img class="aligncenter size-full wp-image-1360" src="http://www.ceturk.com/images/draganddrop2.gif" alt="draganddrop2" width="386" height="407" /></p>
<p>Artık objemizin listBox2 üzerinde sürüklenirkenki ve bırakıldığı andaki durumlarını ayarlamak kaldı.</p>
<p>Objemiz listBox2 nin üzerine geldiğinde yapılacak işlemleri belirlemek için listBox2&#8242;nin DragOver event&#8217;ini şu şekilde düzenliyoruz.</p>
<pre class="brush:csharp">private void listBox2_DragOver(object sender, DragEventArgs e) {

if (e.KeyState == 1) {

e.Effect = DragDropEffects.All;

}

}</pre>
<p>Buradaki DragEventArgs&#8217;dan türemiş e nesnemizin KeyState parametresi ile mouse ve klavyede o an hangi tuşa bastığımızı gözlemliyoruz. KeyState parametresi değer olarak</p>
<p><span style="color: #ff0000;">1     Mouse&#8217;un sol tuşuna basılıyor ise<br />
2     Mouse&#8217;un sağ tuşuna basılıyor ise<br />
5     Shift tuşuna basılıyor ise<br />
9     Ctrl tuşuna basılıyor ise</span></p>
<p>gibi değerler alabileceği gibi kodumuzu</p>
<pre class="brush:csharp">if ((e.KeyState &amp; (8 + 32)) == (8 + 32))

{

e.Effect = DragDropEffects.All;

}</pre>
<p>şeklindede yazabilir ve Ctrl + Alt tuşlarına basıldığında Drop işlemini gerçekleştirmesini sağlayabiliriz.</p>
<p>Burda sık kullandığımız bazı tuşların KeyState değerleride tablo halinde şu şekildedir.</p>
<p><span style="color: #ff0000;">8     Ctrl<br />
32     ALT<br />
4     Shift<br />
(8+32)     Ctrl + ALT</span></p>
<p>Son olarak Drop yani bırakılma durumunda programımızın nasıl davranacağını belirlemeye geldi. Drop olayı listBox2 nesnemizin üzerinde gerçekleşeceğinden listBox2 kontrolümüzün DragDrop event&#8217;ini şu şekilde düzenliyoruz.</p>
<pre class="brush:csharp">private void listBox2_DragDrop(object sender, DragEventArgs e) {

listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));

}</pre>
<p>Burada&#8217;da gördüğünüz üzere Objemiz listBox2 üzerine sürüklenip bırakıldığı anda gerçekleşecek iki satır kodumuz var bunlardan birincisi</p>
<pre class="brush:csharp">listBox2.Items.Add(e.Data.GetData(DataFormats.Text));</pre>
<p>Drag durumundaki objemizi listBox2 içerisine eklemekte&#8230;</p>
<pre class="brush:csharp">listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));</pre>
<p>Drop işlemi tamamlanıp Drag durumundaki objemizi listBox1 içerisinden kaldırıyoruz. Uygulamanızdaki kullanım alanına göre bu işlemi kullanmayabilirsiniz.</p>
<p><span style="text-decoration: underline;">Uygulamamızın son görüntüsü</span></p>
<p><img class="aligncenter size-full wp-image-1361" src="http://www.ceturk.com/images/draganddrop3.gif" alt="draganddrop3" width="378" height="315" /></p>
<p>Buradaki kodlarımızın genel görünümümü kolaylık olsun diye ayrı yayınlayalım.</p>
<pre class="brush:csharp">private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
Point snoktalar = new Point(e.X, e.Y);
int item_indis = listBox1.IndexFromPoint(snoktalar);
if (item_indis == -1)
{
MessageBox.Show("Boş bir alana tıkladınız. Boş alanda drag &amp; drop gerçekleştiremezsiniz.");
return;
}
if (e.Button == MouseButtons.Left) {
listBox1.DoDragDrop(listBox1.Items[item_indis], DragDropEffects.All);
}

}

private void listBox2_DragOver(object sender, DragEventArgs e) {

if (e.KeyState == 1)  {
e.Effect = DragDropEffects.All;
}

}

private void listBox2_DragDrop(object sender, DragEventArgs e) {

listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));

}</pre>
<p>Evet basitçe C# ile Drag &amp; Drop olayını bu şekilde gerçekleştirebiliriz. Giriş kısmında da belirttiğim gibi Drag &amp; Drop olayının anlamlı olması açısından genel kullanımın DML işlemleri için geçerli olduğunu ve burda anlattıklarımın sadece Drag &amp; Drop olayının anlaşılması için olduğunu unutmayın.<br />
<strong><br />
Yasin Sirkecili<br />
yasin@csharpturk.net</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ceturk.com/programlama/csharp-ile-drag-drop.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C# ile Derinlemesine SqlConnection</title>
		<link>http://www.ceturk.com/muhendislik/c-ile-derinlemesine-sqlconnection.html</link>
		<comments>http://www.ceturk.com/muhendislik/c-ile-derinlemesine-sqlconnection.html#comments</comments>
		<pubDate>Sat, 07 Jan 2006 22:36:24 +0000</pubDate>
		<dc:creator>yido</dc:creator>
				<category><![CDATA[Bilgisayar Mühendisliği]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Mühendislik]]></category>
		<category><![CDATA[Programlama]]></category>
		<category><![CDATA[Yazılım Mühendisliği]]></category>
		<category><![CDATA[C# ile Derinlemesine SqlConnection]]></category>
		<category><![CDATA[SqlConnection events:]]></category>
		<category><![CDATA[Transaction ve Isolation Level’lar]]></category>
		<category><![CDATA[Yasin Sirkecili]]></category>

		<guid isPermaLink="false">http://www.ceturk.com/?p=1411</guid>
		<description><![CDATA[Bu makalemizde SQL 7.0 ve yukarısı veritabanlarına bağlanırken kullandığımız SqlConnection sınıfını properties, method ve eventleri ile gözden geçirmeye çalışacağız.
SqlConnection classı System.Data.SqlClient namespace inden gelmektedir. Bu nedenle öncelikle.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
satırını ekleyerek SqlConnection ımızı kullanabilir hale getiriyoruz.
Daha sonra bu class yardımıyla programımızda kullanabilmek için bir SqlConnection nesnesi türetelim.
SqlConnection baglanti = new [...]]]></description>
			<content:encoded><![CDATA[<p>Bu makalemizde SQL 7.0 ve yukarısı veritabanlarına bağlanırken kullandığımız SqlConnection sınıfını properties, method ve eventleri ile gözden geçirmeye çalışacağız.</p>
<p>SqlConnection classı System.Data.SqlClient namespace inden gelmektedir. Bu nedenle öncelikle.</p>
<p>using System;<br />
using System.Collections.Generic;<br />
using System.ComponentModel;<br />
using System.Data;<br />
using System.Drawing;<br />
using System.Text;<br />
using System.Windows.Forms;<br />
using System.Data.SqlClient;</p>
<p>satırını ekleyerek SqlConnection ımızı kullanabilir hale getiriyoruz.</p>
<p>Daha sonra bu class yardımıyla programımızda kullanabilmek için bir SqlConnection nesnesi türetelim.</p>
<p><code>SqlConnection baglanti = new SqlConnection();</code></p>
<p>Şimdi SqlConnection la birlikte kullananabileceğimiz ve veritabanına bağlanırken bize avantaj, dezavantaj sağlayayan propertieslermizi inceleyelim.</p>
<p>Öncelikle bir örnek olması açısından bu baglantımıza ait connection string’imizi yazıp daha sonra bu yazdıklarımızı tek tek inceleyelim.</p>
<p><code>baglanti.ConnectionString = "Data Source=localhost; database=yasindb; uid=sa; pwd=sirkecili; pooling=true; connection lifetime=20; connection timeout=25; packet size=1024;";</code></p>
<p>Connection String Properties:</p>
<p><strong>Data Source:</strong> Bağlanacağımız bilgisayarın adı yada ip numarasını belirtiriz.</p>
<p><strong>Database:</strong> Bağlanacağımız database’in adını belirtiriz.</p>
<p><strong>Usser ID(uid):</strong> Bağlanacağımız sql veritabanına hangi kullanıcı adı ile gireceğimizi belirtiriz.</p>
<p><strong>Password (pwd):</strong> user id mize ait şifremizi belirtiriz.</p>
<p><strong>Pooling:</strong> Database’ e birkere bağlanıp verileri okuduktan yada yazdıktan sonra database ile olan bağlantıyı ya biz sonlandırırız. Ya imleç connection nesnesinin etki alanından çıkınca otomatik olarak sonlandırılır. Yada database ile belli bir süre işlem yapmayınca devreye garbage collectors girerek bağlantının sonlanmasını sağlar.  Bu tip durumlarda aynı veritabanından aynı yada daha fazla veriyi alırken kullanıcı performansın üst düzeyde olmasını hatta sanki bellekten okunuyormuş gibi olmasını ister. Pooling bu noktada devreye girer ve daha önce database’den alınmış olan verileri çok daha hızlı olarak tekrar istemciye gönderimesini sağlar. İki farklı değer alabilir. True olursa aktif, false olursa pasiftir.</p>
<p>Dikkat etmemiz gereken nokta pooling yapısı aynı connection string ile oluşan bağlantılar için geçerlidir.</p>
<p>Pooling’in özelliğinin sağladığı performans katkısını görmek için database ile olan bağlantımızı açıp kapatarak bir test yapalım.</p>
<p><code>SqlConnection baglanti1 = new SqlConnection();<br />
SqlConnection baglanti2 = new SqlConnection();</code></p>
<p><code>private void Form1_Load(object sender, EventArgs e)<br />
{<br />
baglanti1.ConnectionString = "Data Source=localhost; database=yasindb; uid=sa; pwd=sirkecili; pooling=true; connection lifetime=10; connection timeout=5; packet size=1024;";<br />
baglanti2.ConnectionString = "Data Source=localhost; database=yasindb; uid=sa; pwd=sirkecili; pooling=false; connection lifetime=10; connection timeout=5; packet size=1024;";<br />
}</code></p>
<p>private void ac_Click_1(object sender, EventArgs e)<br />
{<br />
DateTime baslangic = DateTime.Now;<br />
for (int i = 0; i &lt; 9999; i++)<br />
{<br />
baglanti1.Open();<br />
baglanti1.Close();<br />
}<br />
DateTime bitis = DateTime.Now;<br />
TimeSpan fark = bitis &#8211; baslangic;<br />
label1.Text = fark.TotalMilliseconds.ToString();</p>
<p>}</p>
<p>private void kapat_Click(object sender, EventArgs e)<br />
{<br />
DateTime baslangic = DateTime.Now;<br />
for (int i = 0; i &lt; 9999; i++) {<br />
baglanti2.Open();<br />
baglanti2.Close();<br />
}<br />
DateTime bitis = DateTime.Now;<br />
TimeSpan fark = bitis &#8211; baslangic;<br />
label2.Text = fark.TotalMilliseconds.ToString();</p>
<p>}</p>
<p><img class="aligncenter size-full wp-image-1412" src="http://www.ceturk.com/images/c-ile-derinlemesine-sqlconnection1.gif" alt="c-ile-derinlemesine-sqlconnection1" width="291" height="154" /></p>
<p>Gördüğünüz üzere pooling özelliği Sql bağlantılarımızda performansımıza yüksek düzeyde etkinlik sağlamaktadır.</p>
<p><strong>Min pool size:</strong> Aktif olabilecek minimum baglanti sayısını belirtir.<br />
<strong>Max pool size:</strong> Aktif olabilecek maksimum baglanti sayısını belirtir.</p>
<p><strong>Connection Lifetime:</strong> Açmış olduğumuz connection’ın ne kadar süre aktif olacağını bu özellikle belirleriz.</p>
<p><strong>Connection Timeout: </strong>Veritabanına bağlanırken zaman zaman server taraflı, zaman zaman client taraflı yada diğer iletişim problemleri nedeniyle bağlantının sağlanamadığı durumlar gerçekleşir. Bu durumlar, Programımızın ne kadar süre içinde veritabanına bağlanması gerektiğini hatta daha açık bir cümleyle… “ne kadar sürede veritabanına bağlanamazsa hata vereceğini” belirleriz. Default olarak değeri 15sn dir. Eğer connection stringde belirtmez isek. 15 sn olarak kabul edilir.</p>
<p><strong>Packet Size:</strong> Performans açısından çok önemli bir kriter olan packet size. Bağlantının kaç bytle’lık paketler halinde veri iletişimi sağlayacağını belirtir. Default olarak değeri 8192 byte olup minimum değeri: 512 maximum değeri: 32767 byte yani 32 kb’dır. Alacağımız verinin büyüklüğüne göre seçeceğimiz bu değer. Genellikle resim yada benzeri büyük boyutlu içerikler için 32767 text içerikler içinse daha düşük değerleri içermelidir. Bağlantı sağlanmadan önce connection stringde belirtilmesi gerektiği için</p>
<p><code>baglanti.Open();<br />
baglanti.PacketSize = 2048;</code></p>
<p>gibi sonradan belirttiğimiz bir kullanımda hata oluşturacaktır.</p>
<p><strong>Properties</strong></p>
<p><strong>State:</strong> Kod bloklarında çoğu zaman baglantinin ne zaman açılıp ne zaman kapandığı belirtmiş olsakta kullanıcının işlem yapma zamanını göz önünde bulundurduğumuzda baglantinin durumunu tekrar gözden geçirmemiz gerekir. Örneğin eğer bağlantı açıksa kullanıcının istediği işlemi tekrar bağlantı oluşturmadan daha hızlı yapmasını sağlayabilir. Yada bunun tam tersi durumlarda kullanıcı işlem yapmakta gecikmiş ise bağlantıyı yenilememiz gerektiğini bu özellik sayesinde öğrenebiliriz.</p>
<p><code>SqlConnection baglanti = new SqlConnection();<br />
private void Form1_Load(object sender, EventArgs e)<br />
{</code></p>
<p>baglanti.ConnectionString = &#8220;Data Source=localhost; database=yasindb; uid=sa; pwd=sirkecili; pooling=true; connection lifetime=20; connection timeout=5; packet size=1024; connection lifetime=5;&#8221;;<br />
baglanti.Open();</p>
<p>}</p>
<p>private void durum_Click(object sender, EventArgs e)<br />
{<br />
if (baglanti.State == ConnectionState.Open)<br />
{<br />
MessageBox.Show(&#8220;bağlantı açık&#8221;);<br />
}<br />
else {<br />
MessageBox.Show(&#8220;baglanti kapalı&#8221;);<br />
}</p>
<p>}</p>
<p>private void ac_Click(object sender, EventArgs e)<br />
{<br />
if (baglanti.State == ConnectionState.Closed) // Açık olan bağlantıyı tekrar açmak hata mesajı üreteceğinden if döngüsüne aldık.<br />
{<br />
baglanti.Open();<br />
}<br />
else<br />
{<br />
MessageBox.Show(&#8220;Bağlantı zaten açık&#8221;);<br />
}<br />
}</p>
<p>private void kapat_Click(object sender, EventArgs e)<br />
{<br />
baglanti.Close(); }</p>
<p><img class="size-full wp-image-1413 alignleft" src="http://www.ceturk.com/images/c-ile-derinlemesine-sqlconnection2.jpg" alt="c-ile-derinlemesine-sqlconnection2" width="292" height="293" /><img class="aligncenter size-full wp-image-1414" src="http://www.ceturk.com/images/c-ile-derinlemesine-sqlconnection3.jpg" alt="c-ile-derinlemesine-sqlconnection3" width="287" height="291" /></p>
<p><em><strong>State yapsının öğrenebileceğimiz durumları şöyledir:</strong></em><br />
<img class="aligncenter size-full wp-image-1415" src="http://www.ceturk.com/images/c-ile-derinlemesine-sqlconnection4.gif" alt="c-ile-derinlemesine-sqlconnection4" width="208" height="120" /></p>
<p><span style="color: #ff0000;">a) Broken: Belirtilen bağlantı daha önce closed olmuş ve daha sonra tekrar açılmıştır.<br />
b) Closed: Bağlantı kapalı durumdadır.<br />
c) Connecting: Bağlantı kurulma aşamasındadır.<br />
d) Executing: Bağlantı üzerinde o anda bir komut işlem görmektedir.<br />
e) Fetching: Veri alışverişi yapılmaktadır.<br />
f) Open: Bağlantı Açıktır.</span></p>
<p>Yazılın ilerleyen bölümlerinde StateChange olayını inceleyecek ve bu olay yardımıyla bağlantı durumu değiştiğinde direkt bilgi alabileceğimizi göreceğiz.</p>
<p>ServerVersion: Çalıştığımız database in versiyonunu öğrenmemize yarar. Geriye server’ın versiyon bilgisini dönderir.</p>
<p><em>Örnek kullanım:</em></p>
<p><code>SqlConnection baglanti = new SqlConnection();<br />
private void Form1_Load(object sender, EventArgs e)<br />
{<br />
baglanti.ConnectionString = "Data Source=localhost; database=yasindb; uid=sa; pwd=sirkecili; pooling=true; connection lifetime=20; connection timeout=5; packet size=1024; connection lifetime=5;";<br />
baglanti.Open();<br />
}<br />
private void durum_Click(object sender, EventArgs e)<br />
{<br />
if (baglanti.State == ConnectionState.Open)<br />
{<br />
MessageBox.Show("Database version: " + baglanti.ServerVersion);</code></p>
<p>}<br />
else {<br />
MessageBox.Show(&#8220;baglanti kapalı&#8221;);<br />
}</p>
<p><img class="aligncenter size-full wp-image-1416" src="http://www.ceturk.com/images/c-ile-derinlemesine-sqlconnection5.gif" alt="c-ile-derinlemesine-sqlconnection5" width="200" height="201" /><br />
<strong>SqlConnection Methods:</strong></p>
<p><strong>ChangeDatabase: </strong>Bazı durumlarda bağlantımız açık iken connection stringde belirtilen database’den başka bir database geçmemiz ve ordaki verilere ulaşmamız gerekebilir. Bu durumlarda ChangeDatabase methodu ile aynı serverdaki başka bir database e geçebiliriz. Ancak unutmayalımki bu durumda diğer Database’e bağlanırken windows authentication yada mssql yetkili kullanıcı parolası kullanmamız gerekir.</p>
<p><code>baglanti.ChangeDatabase("DigerDatabase");</code></p>
<p><strong>CreateCommand:</strong> Database ile veri iletişimi sağlarken kullandığımız SqlCommand’larda hepimizin genellikle kullandığı</p>
<p>1-) SqlCommand KomutAdi = new SqlCommand(&#8220;select * from tablo&#8221;, baglanti);</p>
<p>yada</p>
<p>2-) SqlCommand KomutAdi = new SqlCommand();<br />
KomutAdi.Connection = baglanti;</p>
<p>Gibi satırlar ile… bilirizki hangi SqlCommand’ın hangi SqlConnection ile ilişkilendirildiğini belirtmemiz gerekir.</p>
<p>SqlConnection sınıfına ait bu methodlada bağlantı açık konumdayken o bağlantıya ait yeni bir SqlCommand nesnesi yaratırız.</p>
<p><em>Örnek kullanım:</em></p>
<p><code>SqlCommand KomutAdi = baglanti.CreateCommand();</code></p>
<p><strong>Open:</strong> Kapalı konumda olan bağlantının açılmasını sağlar. Dikkat edilmesi gereken iki nokta vardır.</p>
<p>a) Açık olan bağlantıyı tekrar açmaya kalkarsanız hata verir.</p>
<p>b) SQL bağlantılarında bağlantı oluşurken server’dan cevap alınamaması gibi durumlar farklı sebeplerden ötürü sıklıkla karşımıza çıkar. Bu yüzden Open methodunun kullanıldığı noktalarda try – catch blogu kullanmak yada daha farklı olarak connection timeout süresinden önce hatayı yakalayacak bir timer oluşturarak kullanıcıyı hata mesajı ile karşı karşıya getirmemek önem teşkil eder.</p>
<p>Örnek kullanım:</p>
<p><code>try<br />
{<br />
baglanti.Open();<br />
}<br />
catch {<br />
MessageBox.Show("bağlantı kurulamadı");<br />
}</code></p>
<p>Close: Açık olan bağlantının kapatılmasını sağlar.</p>
<p>Örnek Kullanım:</p>
<p><code>Baglanti.Close();</code></p>
<p>Transaction ve Isolation Level’lar:</p>
<p>Transaction database bağlantılarında en önemli yere sahip noktalardan biridir. Database’e bağlı iken yaptığınız işlemlerde oluşan local yada server taraflı yada diğer iletişim aksilikleri. Yada aynı anda başka bir client’la aynı database’e bağlı olduğunuz ve değişiklik yaptığınız durumlarda oluşabilecek birçok hata mevcuttur. Bu gibi durumlarda transaction kullanarak bu olası hatalardan bazılarının önüne geçmemiz mümkün olmasada verilerimizin kaybolmasına karşın güvenliğini sağlamamız mümkün. Örnek vermek gerekirse;</p>
<p>Varsayalım belli işlemler ile puan topladığımız bir oyun programladık. Ve oyunumuza nick belirterek girişler sağlayabiliyor. Hatta topladığımız puanları bu nickler arasında birbirine göndererek paylaşımını da sağlayabiliyoruz. Böyle bir hikayede Oyuncu1 nick’i ile topladığımız 1000 puanın 500’ünü “Oyuncu2” adlı nick’e aktarıyoruz. Aktarma sırasında gerçekleşecek bir elektrik kesintisi yada benzeri anlık aksaklıklar sonucu Oyuncu1’den çıkmış olan 500 puan Oyuncu2’ye varmadan kaybolacaktır.</p>
<p>İkinci bir varsayımda ise başka birinin size puan transfer ettiği bir durumda sizin sağladığınız bağlantıda 1000 puanınız olduğu görünürken o anda başka biri size puan transfer ediyor. Ancak siz puanınızı 1000 olarak görmeye devam ediyorsunuz. Bu varsayımda ise bağlantı sağlandığında veriler üzerindeki yetkinliğinizi tanımlamanız gerekiyor.</p>
<p><em>Örnek kullanım:</em></p>
<p><code>private void durum_Click(object sender, EventArgs e)<br />
{<br />
SqlConnection baglanti = new SqlConnection();</code></p>
<p>SqlParameter AktarilacakPuan = new SqlParameter();<br />
SqlParameter AktarilacakOyuncu = new SqlParameter();</p>
<p>AktarilacakPuan.ParameterName = &#8220;@puan&#8221;;<br />
AktarilacakPuan.Value = textBox2.Text;</p>
<p>AktarilacakOyuncu.ParameterName = &#8220;oyuncu&#8221;;<br />
AktarilacakOyuncu.Value = textBox1.Text;</p>
<p>SqlTransaction sqltrans = new SqlTransaction(); // Transaction nesnemizi yaratıyoruz<br />
baglanti.ConnectionString = &#8220;Data Source=localhost; database=yasindb; User ID=sa; Password=sirkecili; pooling=true; connection lifetime=100; connection timeout=25; packet size=2048;&#8221;;<br />
baglanti.Open();<br />
SqlCommand ekle = baglanti.CreateCommand(); // baglanti adındaki SqlConnection nesnemizde kullanmak için komut yaratıyoruz.<br />
ekle.CommandType = CommandType.Text;<br />
ekle.CommandText = &#8220;update puanlar set puan=puan + @puan where oyuncu=@oyuncu&#8221;;<br />
ekle.Parameters.Add(AktarilacakPuan);</p>
<p>try<br />
{<br />
sqltrans = baglanti.BeginTransaction(IsolationLevel.ReadCommitted); // ReadCommited olarak çalışmasını istediğimiz transaction&#8217;ımızı başlatıyoruz.<br />
ekle.ExecuteNonQuery();<br />
sqltrans.Commit(); // işlemin başarıyla gerçekleştiğini onaylıyoruz. Ve böylelikle puan karşı tarafa puan göndermiş oluyoruz.<br />
MessageBox.Show(&#8220;aktarım başarıyla tamamlandı&#8221;);<br />
baglanti.Close();<br />
}<br />
catch {<br />
sqltrans.Rollback(); // işlemin başarısız olduğunu belirterek transaction&#8217;ın başladığı noktaya dönüyor ve puanın gitmemesini sağlıyoruz<br />
MessageBox.Show(&#8220;aktarım gerçekleştirilemedi&#8221;);<br />
}</p>
<p><strong>Not: </strong>verimiz commit olduktan sonra bizden düşmesi gereken puanı Önemli olan konunun anlaşılması düşüncesiyle es geçtim.</p>
<p>Burdaki kodlamada belirttiğim</p>
<p><code>sqltrans = baglanti.BeginTransaction(IsolationLevel.ReadCommitted);</code></p>
<p>satırındaki isolationLevel dikkatinizi çekmiştir. Şimdi bu level’ların ne anlama geldiğini sırayla inceleyelim.</p>
<p><strong>Chaos:</strong> O anda başkası database üzerinde değişiklik yapıyor ise sizin değişiklik yapmanıza izin vermez.</p>
<p><strong>ReadCommited :</strong> Database’e bağlandığınızda o anda başkası değişiklik yapıyorsa onun commit olmuş verilerine ulaşmanızı. Henüz onaylanmayan değişikliklerini görmemenizi sağlar.</p>
<p><strong>ReadUncommited:</strong> Başka birini değişiklik yaptığı anda kişinin verileri henüz commit olmamış dahi olsa onları görüntüleyebilmenizi sağlar.</p>
<p><strong>RepeatableRead:</strong> Siz verileri okur iken bağlantı sağlayan diğer Client’ların değişiklik yapmamasını sağlarsınız.</p>
<p><strong>Serializable:</strong> Database’deki tüm verileri dondurarak hiçbir satıra güncelleneme yapılamamasını ve yeni satır eklenememesini sağlar.</p>
<p><strong>SqlConnection events:</strong></p>
<p><strong>StateChange:</strong> Bu event yardımıyla connection durumunda bir değişiklik meydana geldiğinde istediğimiz bir kod bloğunun işletilmesini sağlarız. Böylelikle bağlantı durumunda bir değişiklik olduğu anda bilgi almamızıda mümkün kılmış oluruz.</p>
<p>Bunun için önce bağlantımızı oluşturacak. Daha sonra bu bağlantıya ait bir statechange eventi yaratacak. Ve bu event yardımıyla durum bilgisi değiştiğinde ekrana MessageBox çıkartıp durum bilgisinin hangi konumdan hangi konuma geçtiğini görünteleyeceğiz.</p>
<p><em>Örnek Kullanım:</em></p>
<p><code>SqlConnection baglanti = new SqlConnection(); // bağlantımızı oluşturuyoruz.</code></p>
<p>private void Form1_Load(object sender, EventArgs e)<br />
{<br />
baglanti.ConnectionString = &#8220;Data Source=localhost; database=yasindb; uid=sa; pwd=sirkecili; pooling=true; connection lifetime=10; connection timeout=5; packet size=1024;&#8221;;<br />
baglanti.StateChange += new StateChangeEventHandler(durumbilgisi); // kod ile oluşturduğumuz sqlconnection nesnemize ait durumbilgisi adında statechange eventi tanımlıyoruz.<br />
}</p>
<p>private void ac_Click_1(object sender, EventArgs e)<br />
{<br />
if (baglanti.State == ConnectionState.Closed) // bağlantı kapalıysa&#8230;<br />
{<br />
baglanti.Open(); // bağlantıyı açıyoruz.<br />
}<br />
}</p>
<p>private void kapat_Click_1(object sender, EventArgs e)<br />
{<br />
baglanti.Close(); // bağlantıyı kapatıyoruz.<br />
}</p>
<p>private void durumbilgisi(object sender, StateChangeEventArgs e) // oluşturduğumu durumbilgisi eventine StateChangeEventArgs parametresini vererek durum bilgisini gözlemliyoruz.<br />
{<br />
MessageBox.Show(&#8220;Bağlantı &#8221; + e.OriginalState.ToString() + &#8221; konumundan &#8221; + e.CurrentState.ToString() + &#8221; konumuna geçti&#8221;); // bağlantı durumu değiştiğinde durumu gözlemliyoruz.</p>
<p>}</p>
<p><img class="aligncenter size-full wp-image-1417" src="http://www.ceturk.com/images/c-ile-derinlemesine-sqlconnection6.gif" alt="c-ile-derinlemesine-sqlconnection6" width="294" height="225" /><img class="aligncenter size-full wp-image-1418" src="http://www.ceturk.com/images/c-ile-derinlemesine-sqlconnection7.gif" alt="c-ile-derinlemesine-sqlconnection7" width="292" height="222" /></p>
<p>Dikkat ederseniz e.CurrentState ile bağlantının durum değiştirmeden önceki halini e.OriginalState’de o anki durumunu yansıtmaktadır.</p>
<p>Evet bir makalenin daha sonuna geldik.Umarım yararlı olmuştur.<br />
Hepinize mutlu günler dilerim.</p>
<p>İyi çalışmalar.</p>
<p><strong>Yasin Sirkecili<br />
yasin@sirkecili.com </strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ceturk.com/muhendislik/c-ile-derinlemesine-sqlconnection.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
