Aklımda Kalası Kelimeler

* давайте работать вместе
* Zarf ve Mazruf, Zerafet(xHoyratlık) ile aynı kökten(za-ra-fe) gelir
* Bedesten
* Suç subuta ermiştir - Suç sabit olmuştur

27 Şubat 2013 Çarşamba

Action ve Func ile asenkron metot çağrı

using System;
using System.Collections.Generic;
using System.Threading;

namespace KlinikOzetTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("----------------- aksiyonParametresiz ---------");
            #region 
            // Action tipli değişkenlerin asenkron çağrıların, BeginInvoke ile çağırdığımız metotları 
            // EndInvoke ile sonlandırılımalıdır sonuç dönsün ve varsa hafızadaki thread fırlatılsın.
            Action aksiyonParametresiz = DonussuzParametresizMetot;
            Console.WriteLine("BeginInvoke Öncesi: " + DateTime.Now.ToString());
            object o = null;
            IAsyncResult iResult = aksiyonParametresiz.BeginInvoke(delegate { Console.WriteLine("döndüm ben"); }, o);
            Console.WriteLine("BeginInvoke sonrası: " + DateTime.Now.ToString());
            while (!iResult.IsCompleted)
            {
                Console.WriteLine("BeginInvoke tamalanmadı: " + DateTime.Now.ToString());
                if (iResult.IsCompleted)
                {
                    Console.WriteLine("EndInvoke öncesi: " + DateTime.Now.ToString());
                    aksiyonParametresiz.EndInvoke(iResult);
                    Console.WriteLine("EndInvoke sonrası: " + DateTime.Now.ToString());
                }
                
            }

            #endregion

            Console.WriteLine("----------------- aksiyonParametreli ---------");
            #region Parametreli Action değişkeninin çalıştırılması
            int paramInt = 12;
            float paramFloat = 12f;
            Action<string, int, float> aksiyonParametreli = DonussuzParametreliMetot;
            aksiyonParametreli("param string", paramInt, paramFloat);
            #endregion

            Console.WriteLine("----------------- fonksiyonParametresiz ---------");
            Func<string> fonksiyonParametresiz = DonuslüParametresizMetot;
            string sDonenSonuc = fonksiyonParametresiz();

            Console.WriteLine("----------------- fonksiyonParametreli ---------");
            Func<string, int, float, int> fonksiyonParametreli = DonuslüParametreliMetot;
            Console.WriteLine("Invoke Öncesi: "+DateTime.Now.ToString());
            int iDonen = fonksiyonParametreli.Invoke("param param", 14, 10f);
            Console.WriteLine("Invoke Sonrası: " + DateTime.Now.ToString());
            
        }

        #region VOID dönüşlü metotlar ACTION ile referans edilebilir.
        static void DonussuzParametresizMetot()
        {
            int i = 0;
            while (i < 10)
            {
                Thread.Sleep(500);
                i++;
            }
            Console.WriteLine(DateTime.Now);
        }

        static void DonussuzParametreliMetot(string _s, int _i, float _f)
        {
            Console.WriteLine(DateTime.Now);
        } 
        #endregion

        #region DÖNÜŞ tipli metotlar FUNC ile değişkene atanabilir
        static string DonuslüParametresizMetot()
        {
            Console.WriteLine(DateTime.Now);
            return DateTime.Now.ToShortDateString();
        }

        static int DonuslüParametreliMetot(string _s, int _i, float _f)
        {
            int i = 0;
            while (i < 10)
            {
                Thread.Sleep(500);
                i++;
            }
            Console.WriteLine(DateTime.Now);
            return 19;
        } 
        #endregion

    }
}
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:47
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
27.02.2013 15:08:48
BeginInvoke tamalanmadı: 27.02.2013 15:08:48
EndInvoke öncesi: 27.02.2013 15:08:48
döndüm ben
EndInvoke sonrası: 27.02.2013 15:08:48
----------------- aksiyonParametreli ---------
27.02.2013 15:08:48
----------------- fonksiyonParametresiz ---------
27.02.2013 15:08:48
----------------- fonksiyonParametreli ---------
Invoke Öncesi: 27.02.2013 15:08:48
27.02.2013 15:08:53
Invoke Sonrası: 27.02.2013 15:08:53
Press any key to continue . . .
Action,Func ya da Predicate: Func vs. Action vs. Predicate
Action için Türkçe kaynak: http://www.yazilimdevi.com/Makaleler-1198-cSharp-action-tipini-dogru-kullanmak.aspx
Daha önceden yazdığım: Form harici bir sınıftan formun kontrollerine erişmek
Dışarıdan bir referans: www.muratguvenc.net
[Begin/End]Invoke Ne işe yarar: Delegate.BeginInvoke()/EndInvoke() implementation ve dotnetcurry.com

21 Şubat 2013 Perşembe

Android - SDCard erişimi

String sdcard = System.getenv("EXTERNAL_STORAGE");

// File.separator = /
java.io.File f = new java.io.File(baseDir + java.io.File.separator + fileName);



Galaxy GT-N8005'in Bağlı Cihazlar Listesinde Görünmesi

Sorun sürücü problemi ve Samsung'un sürücü sayfasından indirilerek çözülüyor.




19 Şubat 2013 Salı

Visual Studio'nun uzun satırları keserek aşağı almasından şikayetçiyim hakim bey

Keske stackoverflow cevabını buraya hızlıca embed edebilecek bir şey olsaydı:
Aşağıdaki cevabın referansı şudur:http://stackoverflow.com/a/238737/104085

Cevap ise Resharper'da aşağıdaki resme ulaşım işareti kaldırmakta:

15 Şubat 2013 Cuma

E-Reçete İlaç Listesi sayfasından excel dosyasını indirmek ve içeriğini SQL tablosuna girmek

SKRS E-Reçete İlaç Listesi adresindeki excel dosyalarını indirmek ve MSSQL veritabanına atmak isitiyorum.

Adım adım ne nasıl yapılıyor bakalım.

İnternet sayfasından dosya adreslerini bulup indirmek

Bir web sayfasını indirmek istiytorsanız yöntem çok: WebClient Class, HttpRequest Class
Ben yaygın olan WebClient'ı kullandım:
string sDomain = "http://www.iegm.gov.tr/";
string sPage = "Default.aspx?sayfa=erecete_liste&lang=tr-TR";
WebClient wc = new WebClient();
// sayfa UTF8 kodlamasıyla yayında olsun
wc.Encoding = Encoding.UTF8;
string s = wc.DownloadString(sDomain + sPage);

Html içindeki bir elementi bulmak istiyorsanız en kestirmeden Parsing HTML Tags in C# makalesindeki kodu uygulayabilirsiniz.
HtmlTag tag;
var parse = new HtmlParser(s);
while (parse.ParseNext("a", out tag))
{
    string value;
    if (tag.Attributes.TryGetValue("href", out value))
    {
        // Excel dosyalarının isimlerindeki ortak metin
        if (value.IndexOf("farmasotik_urunler_listesi") > 0)
        {
            Uri uri = new Uri(sDomain + value);
            // URL üzerinde dosya adını split etilmiş Segmenets özelliğinin sonunda bulacağız. 
            wc.DownloadFile(uri, @"c:\Temp\" + uri.Segments[uri.Segments.Length - 1]);
        }
    }
}

Dosyalar indiğinde bir excel dosyasına bakalım ve yapısını görelim:


Excel içindeki verileri çekip VT'ye aktarma

Provider sağlam olmalı. Eğer *.xlsx dosyalarıyla boğuşmak istiyorsanız Microsoft Access Database Engine 2010 Redistributable indirmeli ve kurulmalı.

Excel dosyasına az önce kurduğumuz artık Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\\klasorAdi\dosyaAdi;Extended Properties="Excel 8.0;HDR=YES;IMEX=1;" bağlantı cümlesi ile bağlanabiliriz. Bunun için OleDbAdapter sınıfını kullanacağız.
Excel içinde her bir sheet içindeki satırları SELECT * FROM ["sheetAdı"$] ifadesi ile bir DataTable'a çekebiliriz.
public static DataTable f_SheetToDataTable(string _sExcelPath, string _sSheetName)
{
    // OleDbAdaptor'de oluşturduğumuz nesneneyle excel dosyamıza bağlanmak için kullanacağımız bağlantı cümlesi
    string connectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;""", _sExcelPath);
    // Excel içinde çalıştırmak istediğimi sorgumuz
    string query = String.Format("select * from [{0}$]", _sSheetName);
    OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, connectionString);
    DataTable dataSet = new DataSet();
    // Sonucu DataTable içine atalım.
    var dt = new DataTable();
    dataAdapter.Fill(dt);
    return dt;
}
}

DataTable ile dönen bilgilerimizi şimdide veri tabanına aktaralım. Ama önce tabloyu oluşturup bu tablo için otomatik insert ifadelerini oluşturacak şekile getirelim.
CREATE TABLE [dbo].[IlaclarAktif](
 [id] [int] IDENTITY(1,1) NOT NULL,
 [ad] [nvarchar](255) NULL,
 [Barkodb] [float] NULL,
 [firma] [nvarchar](255) NULL,
 [skrs_recete_turu] [nvarchar](255) NULL,
 [skrs_durum] [nvarchar](255) NULL,
 [aciklama] [nvarchar](255) NULL,
 CONSTRAINT [PK_IlaclarAktif] PRIMARY KEY CLUSTERED 
(
 [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

Tabloyu oluşturduktan sonra yansısını kodumuzda oluşturalım ki bize sql cümleleri oluşturtmak zorunda bırakmasın:
string connectionString = "Data Source=10.130.214.20,8586;Initial Catalog=cop;User Id=sa;Password=xxx;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
  connection.Open();
  // SQL cümlemizde maksadımız tablonun şemasını alabilmek. Bu yüzden tek satır veri çekiyoruz.
  using (var adapter = new SqlDataAdapter("SELECT top(1) * FROM TabloAdi", connection))
  {
    using (var builder = new SqlCommandBuilder(adapter))
    {
        // adapter nesnenimizin xxxCommand ozelliklerini set etmek için:
        adapter.UpdateCommand = builder.GetUpdateCommand();
        adapter.InsertCommand = builder.GetInsertCommand();
        adapter.DeleteCommand = builder.GetDeleteCommand();
    }
  }
}

Eğer SqlCommandBuilder sınıfına ait bir nesne oluşturmazsanız InsertCommand oluşturulmamış olacaktır ve aşağıdaki hatayı alırsınız:
Update requires a valid InsertCommand when passed DataRow collection with new rows.

Bir DataTable nesnesi yaratıp içine bir kaç satır ekleyerek bunları VT'ye basacağız. Bunu yapmak için SqlDataAdapter nesnemizin Update() metodunu çağıracağız.
DataTable dtExcel = f_SheetToDataTable("c:\\Temp\\ilacListesi.xls, "AKTİF ÜRÜNLER LİSTESİ");
string connectionString = "Data Source=10.130.214.20,8586;Initial Catalog=cop;User Id=sa;Password=xxx;";
using (var cnn = new SqlConnection(connectionString))
{
    cnn.Open();
    using (var adapter = new SqlDataAdapter("SELECT top(1) * FROM IlaclarAktif", cnn))
    {
        var dtIlaclarAktif = new DataTable("IlaclarAktif");
        try
        {
            // Tablomuzun yapısını(şemasını) dataTable nesnemize aktaralım
            adapter.Fill(dtIlaclarAktif);

            // Excel'de ilk satır sutun adlarını içerdiği için Skip(1)
            // Tablomuzda ilk sütun olan id alanı için her yeni satıra 0 değeri atıyor,
            // dtExcel İçindeki satırları tablomuzdaki sıraya göre object[] tipinde arr nesnesinde oluşturuyor,
            // VT Tablomuzun şemasını ve 1 satırını içeren dtIlaclarAktif tablomuzun satırlarına ekliyoruz.
            var v = dtExcel.Rows.Cast().Skip(1).Select(
                delegate(DataRow row)
                    {
                        var arr = new[] {0, row[0], row[1], row[2], row[3], row[4], row[5]};
                        dtIlaclarAktif.LoadDataRow(arr, LoadOption.Upsert);
                        return arr;
                    });
                        
            // InsertCommand'ın null olması sorun çıkartmasın diye SqlCommandBuilder sınıfından bir nesne yaratıyoruz
            using (var builder = new SqlCommandBuilder(adapter))
            {
                adapter.Update(dtIlaclarAktif);
            }
        }
        catch (Exception ex)
        {
            throw (ex);
        }
    }
}

Excel dosyasındaki bir sheet'i DataTable yapan metot budur:
public static DataTable f_SheetToDataTable(string _sExcelPath, string _sSheetName)
{
    // 
    string connectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;""", _sExcelPath);
    string query = String.Format("select * from [{0}$]", _sSheetName);
    OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, connectionString);
    var dt = new DataTable();
    dataAdapter.Fill(dt);
    return dt;
}

Tüm kodu buraya yapıştırmak isterdim ama zaten siz nasıl olduğunu anladınız ve parçaları bir araya getirmek sizin için artık çocuk oyuncağı değil mi?

Projenin açık kaynak koduna:
http://code.google.com/p/skrs-erecete-ilac-listesi/
adresinden erişebilirsiniz.

DbContext ile Code First yöntemi ve LinqToExcel projesiyle yeniden yaptım

E tabi kod son derece küçüldü. Excel dosyalarını SQL'de tutma kararım uygulamaların taşınması esnasında veri kaybı yaşanmaması içindi.
Önce POCO(Plain Old CLR Object) sınıfları:
ExcelDosya Sınıfı, VT'da excel dosyasını indirdiğimiz URL'yi, hangi tarihli ilaç listesi olduğunu ve excel dosyasını barındıracak.
using System;
using System.Configuration;
using System.Linq;

namespace ExcelToVT
{
    public class ExcelDosya
    {
        public int id { get; set; }
        public string Adres { get; set; }
        public byte[] Dosya { get; set; }
        public DateTime DosyaTarihi { get; set; }
        public DateTime EklenmeTarihi { get; set; }

        public void f_ToVT()
        {
            Kontext ktx = new Kontext(ConfigurationManager.ConnectionStrings["VtCnn"].ConnectionString);
            var a = ktx.ExcelDosyalari.Where(e => e.Adres.Equals(this.Adres)).FirstOrDefault();
            if (a == null)
            {
                ktx.SaveChanges();
            }
        }
    }
}
f_ToVT() metodu hızlı bir şekilde bu dosya yoksa VT'na ekleme işini yapıyor.

Ilac sınıfında excel içinden çekilen satırların VT'na aktarımını(varsa ve değişmişse güncellemesini, yoksa eklenmesini) sağlayacak.
using System.Configuration;
using System.Linq;

namespace ExcelToVT
{
    public class Ilac
    {
        public int id { get; set; }
        public string skrs_ilac_adi { get; set; }
        public decimal skrs_barkod { get; set; }
        public string skrs_firma { get; set; }
        public string skrs_recete_turu { get; set; }
        public string skrs_durum { get; set; }
        public string Aciklama { get; set; }

        public Ilac() { }

        public override bool Equals(object _iegm)
        {
            var iegm = _iegm as IEGMIlac;
            if (iegm == null)
            {
                return false;
            }

            bool bDegisti = iegm.skrs_ilac_adi.Equals(this.skrs_ilac_adi) &&
                            iegm.skrs_durum.Equals(this.skrs_durum) &&
                            iegm.skrs_firma.Equals(this.skrs_firma) &&
                            iegm.skrs_recete_turu.Equals(this.skrs_recete_turu) &&
                            iegm.Aciklama.Equals(this.Aciklama);
            if (!bDegisti)
            {
                this.skrs_ilac_adi = iegm.skrs_ilac_adi;
                this.skrs_durum = iegm.skrs_durum;
                this.skrs_firma = iegm.skrs_firma;
                this.skrs_recete_turu = iegm.skrs_recete_turu;
                this.Aciklama = iegm.Aciklama;
            }
            return !bDegisti;
        }

        public Ilac(string _sCnnStr, IEGMIlac _iegm)
        {
            Kontext ktx = new Kontext(ConfigurationManager.ConnectionStrings[_sCnnStr].ConnectionString);
            Ilac ilac = ktx.Ilaclar.FirstOrDefault(k => k.skrs_barkod.Equals(_iegm.skrs_barkod));
            if (ilac == null)
            {
                this.skrs_barkod = _iegm.skrs_barkod;
                this.skrs_durum = _iegm.skrs_durum;
                this.skrs_firma = _iegm.skrs_firma;
                this.skrs_ilac_adi = _iegm.skrs_ilac_adi;
                this.skrs_recete_turu = _iegm.skrs_recete_turu;
                this.Aciklama = _iegm.Aciklama;
                ktx.Ilaclar.Add(this);
                int a = ktx.SaveChanges();
            }
            else
            {
                if (ilac.Equals(_iegm))
                {
                    ktx.SaveChanges();
                }
            }
        }
    }
}

IEGMIlac sınıfı excel içindeki her satır ilacın önce geçici bir nesneye aktarılmasını, ardından VT'na aktarımında Ilac sınıfından nesne oluşturmada yapıcı metoda parametre olarak geçirilmede kullanılacak.
namespace ExcelToVT
{
    public class IEGMIlac
    {
        public int id { get; set; }
        public string skrs_ilac_adi { get; set; }
        public decimal skrs_barkod { get; set; }
        public string skrs_firma { get; set; }
        public string skrs_recete_turu { get; set; }
        public string skrs_durum { get; set; }
        public string Aciklama { get; set; }
    }
}

Code First için DbContext sınıfından bir türetme yapmanız ve VT yapınızı burada belirtmeniz gerekiyordu(önceki yazılarımda konuyla ilgili bilgi bulabilirsiniz):
using System.Data.Entity;

namespace ExcelToVT
{
    public class Kontext : DbContext
    {
        public Kontext(string connectionString)
            : base(connectionString) { }

        protected override void OnModelCreating(DbModelBuilder mb)
        {
            mb.Entity().Map(p => p.ToTable("Ilaclar"));

            mb.Entity().Property(p => p.id).HasColumnName("id").IsRequired();
            mb.Entity().Property(p => p.skrs_barkod).HasColumnName("skrs_barkod").IsRequired();
            mb.Entity().Property(p => p.skrs_durum).HasColumnName("skrs_durum");
            mb.Entity().Property(p => p.skrs_firma).HasColumnName("skrs_firma");
            mb.Entity().Property(p => p.skrs_ilac_adi).HasColumnName("skrs_ilac_adi");
            mb.Entity().Property(p => p.skrs_recete_turu).HasColumnName("skrs_recete_turu");

            mb.Entity().HasKey(p => p.id);

            mb.Entity().Map(a => a.ToTable("ExcelDosyalari"));
            mb.Entity().HasKey(a => a.id);
        }
        public DbSet Ilaclar { get; set; }
        public DbSet ExcelDosyalari{ get; set; }
    }
}

İşin toplu olarak yapıldığı SKRS3ExcelToDB sınıf:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using HtmlAgilityPack;
using LinqToExcel;

namespace ExcelToVT
{
    static class ExtensionIEnumerable
    {
        /// 
        /// IEnumerable tipinde dizi içinde parametrede verilen metoda dizi elemanlarını ve indeksini geçirir.
        /// 
        /// İçinde dönülecek dizinin tipi
        /// İçinde dönülecek dizi        /// Dizi elemanlarının ve elemanın indeks değerinin gönderileceği metot        public static void ForEachIndex(this IEnumerable e, Action del)
        {
            var i = 0;
            foreach (var cur in e)
            {
                del(cur, i);
            }
        }
    }

    public class SKRS3ExcelToDB
    {
        private string m_CnnStrName;
        public SKRS3ExcelToDB(string _sConnectionStringName)
        {
            m_CnnStrName = _sConnectionStringName;
        }
        public FileInfo f_ToVT(ExcelDosya _excel, string _sSheetName = "AKTİF ÜRÜNLER LİSTESİ")
        {
            if (!Directory.Exists("c:\\Temp"))
            {
                throw new FileNotFoundException("C:\\Temp klasörü bulunamadı! Bu yüzden excel dosyası oluşturulamıyor ve sorgulanamıyor.");
            }

            string sExcelFileName = string.Format("C:\\Temp\\excel_{0}.xlsx", DateTime.Now.ToString("dd.MM.yyyy_hh.mm.ss"));
            var fi = new FileInfo(sExcelFileName);
            File.WriteAllBytes(fi.FullName,_excel.Dosya);

            // Excel'deki verilerimizi DataTable nesnemiz dtExcel'e aktarıyoruz.
            IQueryable dtExcel = f_SheetToDataTable(fi.FullName, _sSheetName);
            var a = "";
            dtExcel.AsEnumerable().ForEachIndex((g, h) =>
                                                    {
                                                        new Ilac(m_CnnStrName, g);
                                                    });
            var b = from iegmIlac in dtExcel
                    select new[] {new Ilac(m_CnnStrName, iegmIlac)};
            return fi;
        }

        public string f_SayfayiIndir(string _sUrl)
        {
            Uri uri = _sUrl != null
                      ? new Uri(_sUrl)
                      : new Uri("http://www.iegm.gov.tr/Default.aspx?sayfa=erecete_liste&lang=tr-TR");

            try
            {
                return new WebClient
                {
                    Encoding = Encoding.UTF8
                }.DownloadString(uri);
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("{0} Adresinden HTML kaynak kodu indirilirken istisna fırlatıldı.", uri.AbsoluteUri));
            }
        }


        FileInfo f_DosyaIndir(Uri _Uri, DirectoryInfo _dirKaydedilecekKlasor)
        {
            try
            {
                string sDosyaYolu = _dirKaydedilecekKlasor.FullName + "\\" + _Uri.Segments[_Uri.Segments.Length - 1];

                new WebClient().DownloadFile(_Uri, sDosyaYolu);
                return new FileInfo(sDosyaYolu);
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        public List f_DosyaIndir(string _sDomain, string _sHtmlCode, DirectoryInfo _dirKaydedilecekKlasor, string _sATaginda = "E-Reçete İlaç Listesi - ")
        {
            var doc = new HtmlDocument();
            doc.LoadHtml(_sHtmlCode);

            var ed = from lnks in doc.DocumentNode.Descendants()
                        where lnks.Name == "a"
                              && lnks.InnerText.StartsWith(_sATaginda)
                        select
                            new ExcelDosya()
                            {
                                Adres = lnks.Attributes["href"].Value,
                                DosyaTarihi = Convert.ToDateTime(lnks.InnerText.Substring(lnks.InnerText.IndexOf(" - ") + 2).Trim(), new DateTimeFormatInfo() { ShortDatePattern = "dd.MM.yyyy" }),
                                EklenmeTarihi = DateTime.Now,
                                Dosya = File.ReadAllBytes(f_DosyaIndir(f_HrefToUri(_sDomain, lnks.Attributes["href"].Value), _dirKaydedilecekKlasor).FullName),
                            };
            return ed.ToList();
        }


        private Uri f_HrefToUri(string _sDomain, string _sAdres)
        {
            return _sAdres.StartsWith("http")
                                  ? new Uri(_sAdres)
                                  : new Uri(_sDomain.Insert(_sDomain.Length, "/") + _sAdres);
        }

        public IQueryable f_SheetToDataTable(string _sExcelPath, string _sSheetName)
        {
            var excel = new ExcelQueryFactory(_sExcelPath);
            var aktif = from c in excel.WorksheetRangeNoHeader("A3", "F65000", _sSheetName)
                        select new IEGMIlac()
                                   {
                                       skrs_ilac_adi = c[0],
                                       skrs_barkod = Convert.ToDecimal(c[1]),
                                       skrs_firma = c[2],
                                       skrs_recete_turu = c[3],
                                       skrs_durum = c[4],
                                       Aciklama = c[5],
                                   };
            return aktif;
        }

        public ExcelDosya f_SonExcelDosyasi()
        {
            List lstExcelDosyalari = f_DosyaIndir("http://www.iegm.gov.tr/", f_SayfayiIndir(null), new DirectoryInfo(@"c:\temp"));
            if (lstExcelDosyalari.Count == 0)
            {
                throw new Exception("Excel dosyaları bulunamadı!");
            }

            Kontext ktx = new Kontext(m_CnnStrName);
            lstExcelDosyalari.ForEachIndex((cur, idx) => ktx.ExcelDosyalari.Add(cur));
            ktx.SaveChanges();
            

            ExcelDosya sayfadakiSonExcel = lstExcelDosyalari.OrderByDescending(p => p.DosyaTarihi).FirstOrDefault();
            return sayfadakiSonExcel;
        }
    }

}

Console Application olduğuna göre bir tetikleyiciye ihtiyacımız var o da:
using ExcelToVT;

namespace NameSpaceProgram
{
    class Program
    {
        private static void Main(string[] args)
        {
            SKRS3ExcelToDB skrs = new SKRS3ExcelToDB("VtCnn");
            ExcelDosya sayfadakiSonExcel = skrs.f_SonExcelDosyasi();
            skrs.f_ToVT(sayfadakiSonExcel, "PASİF ÜRÜNLER LİSTESİ");
            skrs.f_ToVT(sayfadakiSonExcel, "AKTİF ÜRÜNLER LİSTESİ");
        }
    }
}


Proje sayfasına yenisini güncelledim: http://code.google.com/p/skrs-erecete-ilac-listesi/

10 Şubat 2013 Pazar

Fluent API - WithMany İlişkisi

Ref: Julia Lerman
Önceki haliyle sadece HasRequired metoduyla bağlandığında aşağıdaki gib oluşacaktı:
Buradaki durum bir makalenin kesinlikle bir bir Blog'a ait olması haliydi. Sol tarafta Post'un olduğunu düşünürseniz 1-1 ilişkiden söz ediyor oluruz. Bu ilişkide Blog eklenebilir çünkü Post olmasada olur ama Post HasRequired ile Blog özelliği belirtilmeksizin kayıt eklenemez.
Entities in 'Ctx_Blog.Posts' participate in the 'Post_Blog' relationship. 0 related 'Post_Blog_Target' were found. 1 'Post_Blog_Target' is expected.
Hatası alınır. Bu hatanın oluştuğu ekran şudur:
Buna göre Blog soldayken One To Zero Or Many kayıt girişi yapılabilir ki o da şöyledir:

Yukarıdaki gibi bir Blog birden fazla makaleye sahip olabilir. One To Many ilişkisini yaratmak için Fluent API'de WithMany metodunu kullanacağız. Bu metodu zincir bir linq cümlesinde HasRequired metodundan sonra görebiliriz. WithMany metodunu parametresiz çağırdığnız vakit Post tablosunda otomatik olarak bir FK oluşturacaktır. Bu FK, Blog tablosundaki Id ye işaret edecektir çünkü HasRequired metodu hangi tablonun Post tablosunda FK olarak yer aldığını gösterdik.
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity<Post>()
                .HasRequired(p => p.Blog)
                .WithMany();
}
Resimde dikkat edilecek nokta ikinci oluşan FK dır(Blog_Id1).
Bu durum elbette istediğimiz hâl değildir. WithMany metodunda Blog sınıfının hangi özelliğinin Post sınıfından çoklu nesne taşıdığını işaretlemeliyiz. Yani; Post sınıfında bir Blog tanımlanması gerekir (HasRequired(p=>p.Blog) ve Blog sınıfında birden çok(many) Post barındıran özelliğin (WithMany(b=>b.Posts)) işaretlemesi yapılır.
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity()
                .HasRequired(p => p.Blog)
                .WithMany(b=>b.Posts);
}
Buna göre aşağıdaki yapı oluşur:

Buna birde Post tablosundaki Blog_Id FK'sının adını FKBlogId gibi yaratmak istediğimizde önce Post sınıfına FKBlogId özelliğini ekleyelim:
public class Post {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime DateCreated { get; set; }
        public string Content { get; set; }
        public int FkBlogId { get; set; }
        public Blog Blog { get; set; }
    }
Bu durumda hem FKBlogId alanı oluşacak hem de HasRequired(p=>p.Blog) ilişkisinden dolayı FK olarak Blog_Id oluşacaktır. Aşağıdaki gibi bir ekran oluşacak ve yapacak diğer işimizi görebileceksiniz:
FKBlogId tabloda oluştu ama Post-Blog ilişkisinde kullanacağımız FK'nın bu olacağını bildirmemiz gerekiyor o da HasForeignKey metoduyla şöyle yapılır:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity()
        .HasRequired(p => p.Blog)
        .WithMany(b=>b.Posts)
        .HasForeignKey(p=>p.FkBlogId);
}


Tüm Kod:
using System;
using System.Collections.Generic;
using System.Data.Entity;

namespace caFluentAPI {
    class Program {
        static void Main(string[] args) {
            var ctx = new Ctx_Blog();
            var b = new Blog() {
                BloggerName = "CemT",
                Title = "Notlarımdan",
                Posts = new[]{
                    new Post() {Title="Başlık 1", Content = "İçerik 1",DateCreated = DateTime.Now},
                    new Post() {Title="Başlık 2", Content = "İçerik 2",DateCreated = DateTime.Now}
                }
            };
            ctx.Blogs.Add(b);
            ctx.SaveChanges();
        }
    }
    public class Ctx_Blog : DbContext {
        public Ctx_Blog() : base("name=cnn") {
            Database.SetInitializer Ctx_Blog>(new DropCreateDatabaseAlways<Ctx_Blog>());
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder) {
            modelBuilder.Entity<Post>()
                .HasRequired(p => p.Blog)
                .WithMany(b=>b.Posts)
                .HasForeignKey(p=>p.FkBlogId);
        }
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }
    public class Blog {
        public int Id { get; set; }
        public string Title { get; set; }
        public string BloggerName { get; set; }
        public virtual ICollection<Post> Posts { get; set; }
    } 
    public class Post {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime DateCreated { get; set; }
        public string Content { get; set; }
        public int FkBlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

Fluent API - HasRequired - One To Zero Or One ilişkisi

Ref: Julia Lerman
"Bir makale daima bir Blog'a ait olmalıdır" tanımını gerçeklemek için Blog ve Post sınıfları arasında şöyle bir ilişki tanımlanmalıdır:
public class Blog
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string BloggerName { get; set; }
        public virtual ICollection<Post> Posts { get; set; }
    }
    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime DateCreated { get; set; }
        public string Content { get; set; }
        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
Buna göre şu DB oluşur. Dikkat etmeniz gereken yer BlogId alanının Not Null olarak Post tablosunda oluşmasıdır. Bunu yapanın public int BlogId { get; set; } özelliği olduğuna dikkat ediniz.


Eğer Post içindeki BlogId özelliğini "EF zaten public Blog Blog { get; set; } özelliğini görür görmez oluşturacak" derseniz
O zamanda Null bırakılabilir bir makale girişi yapabiliyor olacaksınız. One - To - [Zero Or One](1-0..1) ilişkisini solda Blog olacak şekilde kurdunuz demektir.

Peki public int BlogId { get; set; } özelliğini sınıf içinde tanımlamadan Fluent API ile OnModelCreating metodunda tanımlamak isterseniz:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
}
Post sınıfındaki Blog özelliğinin gerekli olduğunu belirmek için:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Post>().HasRequired(p => p.Blog);
}

Son şekliyle kodumuz:
using System;
using System.Collections.Generic;
using System.Data.Entity;

namespace caFluentAPI {
    class Program {
        static void Main(string[] args) {
            var ctx = new Ctx_Blog();
            var v = new Blog() {
                    BloggerName = "CemT",
                    Title = "Notlarımdan",
                };
            ctx.Blogs.Add(v);
            ctx.SaveChanges();
        }
    }

    public class Ctx_Blog : DbContext {
        public Ctx_Blog() : base("name=cnn") {
            Database.SetInitializer<Ctx_Blog>(new DropCreateDatabaseAlways<Ctx_Blog>());
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder) {
            modelBuilder.Entity<Post>().HasRequired(p => p.Blog);
        }
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }

    public class Blog
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string BloggerName { get; set; }
        public virtual ICollection<Post> Posts { get; set; }
    }
    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime DateCreated { get; set; }
        public string Content { get; set; }
        //public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

8 Şubat 2013 Cuma

Fluent API Nedir, Ne Değildir?

Referans: Configuring Relationships with the Fluent API

Yukarıdaki bağlantıdan edindiklerimi aktaracağım ve birazda okuduğum, izlediklerimden serpiştireceğim. Maksat kavrama seviyesini idrak düzeyine eriştirmek.
Julia Lerman'ın kitapları var Code First ve DbContext üzerine. Gördümki FLUENT API yi kullanmak Annotations'dan hem daha okunaklı hem de tüm yetenekleri barındırması açısından tercih sebebi.

Tablolar arasında ilişkileri Foreign Key ve Navigation özelliklerini kullanarak yapıyoruz. Bu ilişkileri vermek için Fluent API içinde HasRequired, HasOptinal ve HasMany metotlarını kullanıyoruz. Bu metotlar lambda ifadelerini parametre olarak alırlar.

HasKey metodu; tablonun Primary Key alanını ifade etmek için kullanılır ve POCO sınıfında bu değer otomatik oluşturuluyorsa girilmez.
HasRequired metodu; tablo alanlarının boş bırakılamayacağını işaretlemekte kullanılır.
HasMany metodu; bir kolleksiyona yönlenen lambda ifadesi içerir.
HasForeignKey metodu; tabloya başka bir tablonun PK alanını vermek için kullanılır.
http://stackoverflow.com/a/7644906/104085


Tersi yönündeki yönelmeyi de WithRequired, WithOptinal, WithMany metotları sağlar.

VT'yi oluşturmak için kullanacağımız Provider ve VT erişimi için kullanıcı bilgilerini .Config dosyasında tutalım ve DbContext'in yaratıcı metoduna parametre olarak verelim:
<connectionStrings>
    <add name="cnn" connectionString="data source=.; Initial Catalog=cop; Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
  </connectionStrings>

DbContext'i miras alan ve tüm DbSet'leri tutarak VT'nin yaratılması öncesi eylemleri yapacağımız sınıfta VT'yi her defasında silip tekrar yaratalım:
public class Kontext : DbContext
    {
        public Kontext()
            : base("name=cnn")
        {
            this.Database.Delete(); //VT yi silelim
            this.Database.CreateIfNotExists(); //Silinmiş VTyi yaratalım
        }
    }

HasRequired

Veritabanını oluşturmak için aşağıdaki kodlama yapılır ve One To One tablo yapısı oluşturulur. Burada principal Adres olacak ve Kisi sınıfında FK olarak yer alacak.

Eğer Adres bilgisi(Kisi->IkametAdresi) girilmeden Kisi nesnesini VT ye giremezsiniz. İşte aşağıdaki hata sonucu:

Böyle bir ilişkide eğer önce Foreign Key nesnesini girilmeli:


Aşağıdaki POCO yapısına göre daha aşağıda oluşan VT'yi göreceksiniz:
public class Kontext : DbContext
    {
        public Kontext()
            : base("name=cnn")
        {
            this.Database.Delete();
            this.Database.CreateIfNotExists();
        }

        #region DbSets
        public DbSet Kisiler { get; set; }
        public DbSet Adresler { get; set; }
        public DbSet Meslekler { get; set; }
        #endregion

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity().HasKey(p => p.Id)
                        .HasRequired(p => p.FaturaAdresleri)
                        .WithMany();
        }
    }

    public class Kisi
    {
        public int Id { get; set; }
        public string Adi { get; set; }
        public virtual ICollection Mesleks { get; set; }
        public virtual ICollection FaturaAdresleri { get; set; }
        public virtual ICollection TeslimatAdresleri { get; set; }
    }

    public class Meslek
    {
        public int Id { get; set; }
        public string Adi { get; set; }
        public virtual ICollection Kisis { get; set; }
    }

    public class Adres
    {
        public int Id { get; set; }
        public string AcikAdres { get; set; }
    }


Saat 00:35. Yarın ola hayrola ...

One to Zero or One


One to Zero or Many


7 Şubat 2013 Perşembe

Futbolu izlerken Mustafa Denizli'den Yöneticilik Dersi

Mustafa Denizli'nin bugün demecinde söyledikleri:
istediğimiz gibi oynamıyor ama sonuca gidiyoruz(tespit)
Takımın %50-60'ı değişti ve oturması zaman alacak(sebebin tespiti)
Maç ortalaması 2 puan olacak şekilde ilerlemeliyiz ama 2,2 olursa istediğimiz başarı gelecektir.(hedef)
2 Hafta sonra takım istediğimiz şekilde oynayacaktır(takvimlenmiş hedef tayini)

Futboldan çok şey öğreniyorum diye validemle sohbet ederken farkettimki aslında birkaç kişinin söz ve tespitlerine dikkat kesiliyorum.
Denizli sadece iyi futbol değil iyi bir idarecilik nasıl yapılır ve demeç nasıl verilirin dersinide veriyor.

31 Ocak 2013 Perşembe

_ViewStart.cshtml ile veya doğrudan Layout özelliği ile Layout vermek.


_ViewStart.cshtml içinde belirtilen Layout ayarını, bulunduğu klasör ve alt klasörlerdeki tüm "*.cshtml" dosyalarında eğer doğrudan "Layout" özelliği belirtilmemişse ayarlanmış olur.

_ViewStart.cshtml
@{
    Layout = "../Shared/_LayLay2.cshtml";
}

_LayLay2.cshtml
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <header>
        <h1>Benim Ev Sayfam</h1>
        <hr />
    </header>
    <div>
        @RenderBody()
    </div>
    <footer>
        <hr />
        <h5>Copy Right 2013</h5>
    </footer>
</body>
</html>

Index.cshtml
@{
    ViewBag.Title = "innnndex";
}
<div>
    <h1>Hakkımızda</h1>
</div>

Eğer View/Shared klasöründe _Layout.cshtml ve _Layout.mobile.cshtml(mobil cihazlar için ekran şablonu) dosyalarınız varsa isteğin geldiği browser'ın tipine göre layout otomatik seçilecektir.

_PageStart ve RunPage

RunPage() içerisinde tüm sayfa çalışıyor. Ve sayfalardaki istisnalar en üste fırlatılırsa _PageStart içinde yakalanmış ve işlenmiş olur.
@{
    try
    {
        RunPage();
    }
    catch (Exception ex)
    {
        Response.Redirect("~/Error.cshtml?source=" +
            HttpUtility.UrlEncode(Request.AppRelativeCurrentExecutionFilePath));
    }
}

Peki klasik ASP.NET sayfalarında ?

DbContext ile Code First VT Tasarımı

Bununla ilgili tonla video ve yazı var. Benim gözüme çarpan özel noktaları buraya not alacağım. Aralarda gördüklerim arasındaki ilişkilerden bahsedeceğim.

AutoDetectChangesEnabled = true MSDN der ki; Ayarladaki bir değişimi otomatik olarak algılar.
Patrick Desjardin'in blogunda der ki; DbSet'in Add, Attach, Find, Local, Remove metotlarını çağırırken aynı zamanda DbContext'in GetValidationErrors, Entry, SaveChanges metotlarında da çağırılır. DbSet metotlarının çağırlıdığı anda nesnenin veritabanına gitmeden önce değişim geçirip geçirmediği kontrolleri yapılan

public virtual void DetectChanges(bool force = false)
{
    if (this.AutoDetectChangesEnabled || force)
    {
        this.ObjectContext.DetectChanges ();
    }
}
metoduna gidilir. Bu da yüklü VT işlemi yaparken gereksiz bir performans kaybına neden olacağı için AutoDetectChangesEnabled özelliği false yapılır. Patrick tecrübesine dayanarak 100den az nesne için yapılan işlemlerde performans kaybı çok değilken 100'ün üstündeki işlemlerde hissedilir olacağıdır.
Arthur'un dediğine göre ise:
When using most POCO("plain-old" CLR objects) entities the determination of how an entity has changed (and therefore which updates need to be sent to the database) is made by detecting the differences between the current property values of the entity and the original property values that are stored in a snapshot when the entity was queried or attached.
POCO nesneleri VT ye gitmeden önce değişimlere bakılarak hangi nesnenin VT'ye gidip gitmeyeceğine karar verildiği bu DetectChanges metodunu şu kodla (bir dizi[bulk] işlem yaparken) verimli hale getirebilirsiniz:
using (var context = new UnicornsContext())
{
    try
    {
        context.Configuration.AutoDetectChangesEnabled = false;

        // Make many calls in a loop
        foreach (var unicorn in myUnicorns)
        {
            context.Unicorns.Add(unicorn);
        }
    }
    finally
    {
        context.Configuration.AutoDetectChangesEnabled = true;
    }
}

Arthur'un makalesinden yine döndüm dolaştım MSDN0'e geldim. Çünkü alternatif bir yol önermiş:

An alternative to disabling and re-enabling is to leave automatic detection of changes turned off at all times and either call context.ChangeTracker.DetectChanges explicitly or use change tracking proxies diligently. Both of these options are advanced and can easily introduce subtle bugs into your application so use them with care.

Devam etmeden önce Lazy Loading nedir?
Lazy loading is the ability for an entity to perform a query for related entities whenever a navigation property is accessed.
Yani siz nesneyi oluşturduğunuzda tüm bağlantılı diğer nesneleri bind olmasın ve sadece bağlantılı özelliğini çağırdığınızda değerleri bağlansın isterseniz "tembel yükleme" etkin olmalı. Elbette tüm context içinde bunu açıp kapatmanız mümkünken sadece sınıf bazlıda yapabilirsiniz. Aşağıda detaylarından bahsedeceğim.

MSDN derki: Eğer Lazy Loading ve POCO'larının değişimlerini takip etmek isterseniz, EF POCO'larınız için çalışma zamanında PROXY oluşturacaktır. Eğer Lazy Loading proxy istersen değişim takibine sahip olmadan yapabilirsin. Ama değişim takibi istersen Lazy Loading ister istemez proxylerinde gelecektir.
Proxy yaratılması için:
  1. Data sınıfı public erişimde olmalı.
  2. Data sınıfı sealed veya abstract tanımlanmamalı
  3. Data sınıfı parametresiz public veya protected yapıcı metoda sahip olmalı. Parametresiz protected yapıcı metodu CreateObject metodu kullanarak POCO'larınız için proxy oluşturmak istediğinizde kullanılabilir. CreateObject metodu proxy oluşturmayı garantilemez.
  4. Sınıfınız IEntityWithChangeTracker veya IEntityWithRelationships arayüzlerini uygulamaz çünkü PROXY sınıfları bu arayüzleri uygulayacaklardır.
  5. The ProxyCreationEnabled option must be set to true.(E yani.. Şöyleki: context.ContextOptions.ProxyCreationEnabled = true; )
Siz POCO'nuzu yukarıdaki kaidelere göre yaratırsanız aşağıdaki gibi bir yapı oluşur:
public class Kisi
{
    public virtual ICollection Adresler { get; set; }
}
ve bunun peşine dinamik olarak proxy sınıfınız aşağıdaki gibi üretilir:
public class EFKisiProxy : Kisi
{
    public override ICollection Adresler
    {
        get
        {
            DoLazyLoad();
            return base.Adresler;
        }
        set
        {
            base.Adresler= value;
        }
    }
}

Lazy Loading için:
Her bağlantı özelliği ("Her kurumun bir adresi vardır" demek Kurum sınıfı Adres tipinde bir özelliğe sahiptir demektir. Kurum içinde Adres sınıfına bir bağlantı verilecektir) public ve virtual tanımlanmalı ve get metodu mühürlenmiş olmamalı.

Değişim Takibi için:
  1. Bağlantı olarak kullanılan her özellik Data Model içinde mühürlenmiş olmamalı, public ve virtual olmalı.
  2. Eğer birden çok adresi olacaksa bir kurum nesnesinin o halde ICollection<Adres> olarak bu ilişki gösterilmeli.
  3. Eğer nesnen ile birlikte proxy tipini yaratmak istersen ObjectContext içindeki CreateObject metodunu her yeni nesne oluştururken "new" operatörü yerine kullanmalısın.

1:32(am) ve bu arada şunu dinliyorum ;)


Ne diyordu MSDN? Hah, eğer senin CreateObject metot çağrın proxy oluşturamazsa doğrudan POCO'ndan bir nesne yaratır ve sana verir. Bunu anlamak için üretilen nesnenin tipine bakarsın. Tipler aynı değilse bu proxy nesnesidir ve en azından Lazy Loading özelliği vardır. Detaylar How to: Identify that a POCO Entity is a Proxy adresinde.

Yatma saatini geçirdim ama konu konu açtı ve gördümki bu da güzel bir bağlantı olacak CreateObject ya da Create metodu kullanılarak yaratılmış nesnelerin hem alt ilişkileri(public virtual ... ile tanımlı özellikleri için) hemde bu nesnelerin VT ye işlenmeleri ile ilgili. Kaynak stackoverflow ve soru: Create<object> vs new <object> in Entity Framework. Cevaplar güzel ve derlerki: Eğer CreateObject ya da Create metotları ile bir nesne yaratırsan bu nesneler ObjectContext içinde olmayacaklardır. Bunları ObjectContext içine almak istersen Attach etmelisin.
using (var ctx = new MyDbContext())
{
    var user = ctx.Users.Create();
    user.Id = 1;
    ctx.Users.Attach(user);

    var roles = user.Roles;
}
Create ile yarattığın ve Attach ile contexte iliştirdiğin için user.Roles gelecektir. Ama sen new operatörü ile yapsaydın
using (var ctx = new MyDbContext())
{
    var user = new User { Id = 1 };
    ctx.Users.Attach(user);

    var roles = user.Roles;
}
Roles özelliğine asla erişemeyecektin. Tam bu noktada Attaching and Detaching Objects başlıklı MSDN makalesine baktım ve özetle şunları gördüm: Sen bu hariçten nesne yaratma ihtiyacını çeşitli hallerde isteyebilirsin. Mesela normal bir sorgu ile elde edeceğin nesneler object context içindedirler ve yönetilmeleri ve izlenmeleri object context tarafından yapılırken harici bir sorguyla elde ettiğin nesneler context harici oldukları için yönetimleri senin elinde olacaklar. Ya da senin ASP.NET viewstate içinde sakladığın, remote metot veya web servisi çağrısıyla elde ettiğin nesnelerin olabilir. Tüm bunları
  1. System.Data.Objects.ObjectSet.AddObject(...) veya System.Data.Objects.ObjectContext.AddObject(...)
  2. System.Data.Objects.ObjectSet.Attach(...) veya System.Data.Objects.ObjectContext.Attach(System.Data.Objects.DataClasses.IEntityWithKey)ve AttachTo
metotlarıyla ekleyebilirsin. 1 ve 2 farkı primary key değerlerinin olması veya çakışma halinde istisna fırlatılmasıyla ilgili.

İkinci resmimde altı kırmızıyla çizili satırları biraz izah etmiş biraz çevrisiyle kendime notumu almış oldum.
Devamı MSDN'de...

29 Ocak 2013 Salı