FTP Part II - Download

by Volem November 01, 2011 10:01

Yazimin ikinci kismiyla tekrar merhaba.. Ilk bolumde verilen bir ftp klasoru altindaki dosyalarin listesini aliyorduk. Bu yazimda ise herhangi bir dosyayi ya da butun klasoru nasil download edebiliriz konusunu islemeye calisacagim. Download folder icin bir onceki yazimda yer alan GetFileList metodunu kullanacagiz. Neyse sozu fazla uzatmadan biraz kod gorelim.

 

 

public static void Download(string file, string remoteDirectory, string destinationDirectory, string host, string user, string password)
{
    try
    {
        string uri = "ftp://" + host + "/" + remoteDirectory + "/" + file;
        Uri serverUri = new Uri(uri);
        if (serverUri.Scheme != Uri.UriSchemeFtp)
        {
            return;
        }
        FtpWebRequest reqFTP;
        reqFTP = (FtpWebRequest)FtpWebRequest.Create(serverUri);
        reqFTP.Credentials = new NetworkCredential(user, password);
        reqFTP.KeepAlive = false;
        reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
        reqFTP.UseBinary = true;
        reqFTP.Proxy = null;
        reqFTP.UsePassive = false;
        FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
        Stream responseStream = response.GetResponseStream();
        CreateDirectory(destinationDirectory);
        FileStream writeStream = new FileStream(destinationDirectory + "\\" + file, FileMode.Create);
        int Length = 2048;
        Byte[] buffer = new Byte[Length];
        int bytesRead = responseStream.Read(buffer, 0, Length);
        while (bytesRead > 0)
        {
            writeStream.Write(buffer, 0, bytesRead);
            bytesRead = responseStream.Read(buffer, 0, Length);
        }
        writeStream.Close();
        response.Close();
    }
    catch (WebException wEx)
    {
        throw wEx;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

Gordugunuz gibi GetFileList'de yaptigimiza benzer bir is yapiyoruz yalniz bu sefer Method olarak;

reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;

kullaniyoruz. Bu kod bize klasor adresini bildigimiz herhangi bir dosyayi istedigimiz klasore indirmemizi sagliyor. Tahmin ettiginiz gibi Download folder'da yazdigimiz 2 metodu yani GetFileList ve Download'u kullanacak.

public static void DownloadFolder(string sourceDirectory, string destinationDirectory, string host, string user, string password)
{
    try
    {
        string[] files = GetFileList(sourceDirectory, host, user, password);
        foreach (string file in files)
        {
            Download(file, sourceDirectory, destinationDirectory, host, user, password);
        }
    }
    catch(Exception ex)
    {
        throw ex;
    }
}

Umarim acik olmustur. 

Tags: , , , ,

Yazılım | C#

FTP Part I - Dosya Listesi

by Volem October 25, 2011 09:56

 

Merhabalar,

Bugun yeniden 3 asamali bir yazi yazmaya karar verdim. Beraber FTP islemlerini C# ile nasil gerceklestirebilecegimizi gorecegiz. 

Ilk bolumde verilen bir FTP klasorundeki dosya listesini nasil aliriz ona bakacagiz. Ardindan da Download, Upload ve Delete islemlerini nasil yapacagimizi gostermeye calisacagim.


Methodlarin bireysel olarak calisabilmesi icin hepsine FTP server adi, kullanici adi ve sifre bilgilerini parametre olarak gonderiyorum. Ancak siz dilerseniz bu yapiyi bu metodlari gercekleyen sinifin ozellikleri olarak tanimlayabilirsiniz. Boylece sadece o metodu ilgilendiren parametreler ona gidecektir vs.. vs.. :)

Bu bolumde anlatacagim bir klasordeki dosya listesini okuma aslinda diger metodlar ve kullanimlar icin temel olusturacaktir. Sozu fazla uzatmadan kod yazmaya basliyalim..

public static string[] GetFileList(string sourceFolder, string host, string user, string password) {
    StringBuilder result = new StringBuilder();
    WebResponse response = null;
    StreamReader reader = null;
    try
    {
        FtpWebRequest reqFTP;
        reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + host + "/" + sourceFolder + "/"));
        reqFTP.UseBinary = true;
        reqFTP.Credentials = new NetworkCredential(user, password);
        reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
        reqFTP.Proxy = null;
        reqFTP.KeepAlive = false;
        reqFTP.UsePassive = false;
        response = reqFTP.GetResponse();
        reader = new StreamReader(response.GetResponseStream());
        string line = reader.ReadLine();
        while (line != null)
        {
            result.Append(line);
            result.Append("\n");
            line = reader.ReadLine();
        }
        if (result.ToString() != String.Empty)
        {
            result.Remove(result.ToString().LastIndexOf('\n'), 1);
            return result.ToString().Split('\n');
        }
        return new string[0];
    }
    catch (Exception ex)
    {
        if (reader != null)
        {
            reader.Close();
        }
        if (response != null)
        {
            response.Close();
        }
        throw ex;
    }
}

Aslinda yukaridaki kod kendini anlatiyor ancak dikkat edilmesi gereken satir;

reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;

Bu kod parcacigi aslinda ftp sunucusuna gosterdigimiz klasorde en temel command'i olan "dir" calistirmasini soyluyor. Bu komut bize satir satir o klasorde var olan ne varsa listeleyecektir biz de bu satirlari okuyoruz hepsi bu. Bu metodun eksigi aslinda bu klasordekilerin dosya mi yoksa klasor mu olup olmadigini kontrol etmemesidir. Bu konuyu merak eden arkadaslar icin ListDirectory yerine ListDirectoryDetails kullanimini arastirmalarini tavsiye ederim. Kodu basit tutmak amaciyla bu konuya girmiyorum.

Umarim isinize yarar.. Yazimin 2. bolumuyle tekrar gorusmek uzere..

Tags: , , , ,

Yazılım | C#

Email Helper

by Volem October 24, 2011 15:44

public class EmailHelper
{
    const char emailSplitter = ',';    
    public static void Email(string toAddress, string fromAddress, string subject, string attachmentFile, string smtphost, int port)
    {
        string[] emails = toAddress.Split(new char[] { emailSplitter }, StringSplitOptions.RemoveEmptyEntries);
        if (emails.Length > 1)
        {
            foreach (var email in emails)
            {
                Email(email.Trim(), fromAddress, subject, attachmentFile, smtphost, port);
                Thread.Sleep(1000);
            }
            return;
        }
        MailMessage message = new MailMessage();
        message.To.Add(new MailAddress(toAddress));
        message.Subject = subject;
        message.From = new MailAddress(fromAddress);
        message.Body = subject;
        if (File.Exists(attachmentFile))
        {
            message.Attachments.Add(new Attachment(attachmentFile));
        }
        SmtpClient smtp = new SmtpClient(smtphost, port);
        smtp.Credentials = CredentialCache.DefaultNetworkCredentials;
        smtp.Send(message);
    }
}
Merhabalar, 
Uzun zamandan sonra yine arsive katmam gereken bir post cikti :) Herhalde bu yukaridaki kodu 10-15 kere tekrar tekrar yazmisimdir. Yaptigi is aslinda koddan da anlasilacagi uzere cok basit. Bir SMTP server (host) kullanarak parametreleri ile belirttiginiz maili olusturup atiyor. Eger mailinizde attachment yoksa o parametreyi bos gecebilrisiniz.Ayrica toAddress parametresine ',' ile ayrilmis mail adresleri koyabilirsiniz. Boylece birden cok kisiye mail atacaktir.

Herkese kolay gelsin.

Tags: , ,

Yazılım | C#

Hafta Başı ve Hafta Sonu Hesaplama

by Volem July 04, 2011 13:06

Gecenlerde haftayi ve yili bilip de haftanin ilk ve son gununu hesaplama ihtiyacim duydum. Umarim sizin de isinize yarar..


public class CalendarHelper
{
    /// <summary>
    /// Calculates start and end date of a week for a specific year.
    /// </summary>
    /// <param name="year">Year</param>
    /// <param name="week">Week number</param>
    /// <param name="startDate">Calculated start date of week</param>
    /// <param name="endDate">Calculated end date of week</param>
    public static void StartEndDateOfWeek(int year, int week, out DateTime startDate, out DateTime endDate)
    {
        // First of January
        DateTime jan1 = new DateTime(year, 1, 1);
 
        // Calculation is done according to the first day of week is monday but includes the offset,
        // so it will be correct for sunday and other first day of week.
        int daysOffset = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;
        DateTime firstMonday = jan1.AddDays(daysOffset);
 
        // Find the first week.
        int firstWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(jan1, CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule,
            CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek);
 
        if (firstWeek <= 1)
        {
            week -= 1;
        }
        startDate = firstMonday.AddDays(week * 7);
        endDate = startDate.AddDays(6);            
    }
}

Tags: , , , ,

C#

.NET Developer

by Volem March 18, 2011 14:41

Position

Software Developer 

Required Qualifications

Knowledge 

• Knowledge of database architecture and design
• Knowledge of ASP.Net, C#
• Knowledge of Ms SQL, Ajax, Html, Css
• Knowledge of software development
• New and emerging technologies
• English
 
Competences
 
• Team player
• Problem Solving skills
• Analytical minded
• Result driven
• Responsibility
• Technical understanding
• Flexible
 
Experience
 
• Minimum 3 years software development experience.
 
Education
 
• University degree in Computer Science or related area.

Location

Istanbul/Turkey

Tags: ,

Hayat | Yazılım | C# | Web

Game Project - Hopper

by Volem March 11, 2011 12:33

 Merhaba,

 Kisa zaman once bir arkadasimla birlikte online oyun projesi fikriyle heyecanlandik. Genel modeli olusturduk ve bir beyin firtinasi sonucunda  fikrimiz ufak da olsa hayata gecti. Ancak bu asamada bizimle beraber calisacak gonullu yazilimci ve tasarimci arkadaslarla beraber calismak  istiyoruz. Su anda yapimiz .NET Framework 4.0, C# ve MSSQL Server 2008 uzerinde yer aliyor. Versiyon control sistemi olarak da subversion  kullaniyoruz.

 Eger benim de corbada tuzum olsun diyorsaniz ve bir oyun projesinde hobi olarak calismak hosunuza giderse benimle irtibat kurabilirsiniz. ( E-Mail )

Tags:

Yazılım | C#

Localization for ASP.NET

by Volem January 07, 2011 10:42

ASP.NET'te coklu dil destegi vermek icin size kod tekrarini onleyecek bir yapidan bahsetmek istiyorum. Bildiginiz gibi resource dosyalarini kullanarak asp.net icin coklu dil destegini saglayabiliyorsunuz. Yapmaniz gereken uygun isimde resx dosyalarini Global Resources ya da Local Resources klasorleri altina eklemek ardindan da secilen dil icin sayfanin Culture ve UICulture ozelliklerini ayarlamak. Bunun icin benim kullandigim(yazdigim) bir LanguageManager kutuphanesinden bahsedecegim. Yaptigi is basit olarak verilen sayfanin culture ozelliklerini ayarlamak. Ornekten de goreceginiz gibi bir adet siniftan olusuyor.. Kodu genel olarak anlatmayacagim, basit bir yapi var gorulecegi uzere.. LanguageManager'in dil destegi icin kullandigi yapi dil bilgisini session'da tutmasi.. Normalde dil enumeration bilgisi bu class icinde yer almamali ancak kodun calistirilabilir bir durumda olmasi icin bu sinifin icerisine ekledim. Dikkat edilirse ApplyLanguage metodu virtual bir metod ve eger isterseniz bu sinifi inherit ederek dili ister veritabanindan isterseniz cookieden ya da istediginiz herhangi bir servisten okuyacak hale getirebilirsiniz. Bu amacla dispose metodu da virtual olarak set edilmistir ancak Session info icin dispose gerekmiyor o yuzden icerigi bos birakildi ancak ornegin dil bilgisini veritabanindan okursaniz dispose da veritabani baglantisini kapatma islemini yapabilirsiniz..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.Globalization;

namespace Acquistor.Managers
{
    public class LanguageManager : IDisposable
    {
        private System.Web.UI.Page Page;

        public enum Language
        {
            TR,
            EN
        }

        public LanguageManager(System.Web.UI.Page Page)
        {
            this.Page = Page;
        }

        public virtual void ApplyLanguage()
        {
            if (Page.Session["Language"] == null)
            {
                Page.Session["Language"] = Language.TR.ToString();
            }
            switch (Page.Session["Language"].ToString())
            {
                case "TR":
                    SetPageCulture("tr", "tr-TR");
                    break;
                case "EN":
                    SetPageCulture("en", "en-US");
                    break;
                default:
                    SetPageCulture("tr", "tr-TR");
                    break;
            }
        }

        private void SetPageCulture(string uiCulture, string culture)
        {
            Page.UICulture = uiCulture;
            Page.Culture = culture;
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(uiCulture);
        }

        #region IDisposable Members

        public virtual void Dispose()
        {

        }

        #endregion
    }
}
Gelelim bu kodu nasil kullanacaksiniz.. Tabii ki dilini guncellemek istediginiz sayfanin InitializeCulture metodunu override ederek, ama benim tavsiyem genelde tum sayfalarinizda bunu yapmak isteyeceginizi dusundugumden bu isi tanimlayacaginiz base page icerisinde yapmaniz ve sayfalarinizi bu base pageden inherit etmeniz. Boylece tek bir yerden butun sayfalariniza coklu dil destegini vermis olursunuz. Hemen nasil kullanabileceginizi de ufak bir kod ile gostermeye calisayim...
protected override void InitializeCulture()
{
    using (LanguageManager lm = new LanguageManager(Page))
    {
        lm.ApplyLanguage();
    }
    base.InitializeCulture();
}
Umarim isinize yarar.. Herkese kolay gelsin.

Tags: , ,

C# | Web

CLR User Defined Functions Part III

by Volem November 23, 2010 10:08

User defined fonksiyonlarin 3. yazisini biraz geciktirdim malesef.. Isler arti bayram tatili araya girince elde olmayan sebepler olustu. Bugun size clr ile tanimlayabileceginiz aggregate fonksiyonlardan bahsedecegim. Eger daha once goz atmadiysaniz yazimin I. ve II. kisimlarini okumanizi tavsiye ederim. Daha onceki kisimlardan da hatirlayacaginiz uzere kullanici tanimli fonksiyonlar tanimlamak icin belirli kurallara uymamiz gerekiyor. Bir aggregate fonksiyon tanimlamak icin oncelikli olarak sinifinizin IBinarySerialize interface'ini implement etmesi gerekiyor. Bu interface bize iki adet metod sunuyor; Read ve Write.. Bu metodlar SQLServer ile CLR arasindaki asil veri akisini saglayan metodlardir. Ornekten de anlasilacagi uzere olusan veriyi sqlserver'a donduren veya sqlserverdan okuyan metodlardir. Bunun disinda sinifinizin 4 adet daha metod icermesi gerekiyor. Bu metodlar; Init, Accumulate, Merge ve Terminate..(Sizlere tavsiyem verdigim ornegi derlerken metodlardan birini cikarin ve bu sekilde olusan assemblyi sql server'a register etmeye calisin.. Zaten alacaginiz hata sizi yonlendirecektir.)

Sirasiyla metodlari anlatmadan once ornek kodu asagida veriyorum. Bu kod ile grupladiginiz bir kolondaki degerleri virgullerle ayirip baska bir kolonda yazabiliyorsunuz. MySQL'de built-in olan concat aslinda tam olarak concat_ws (concat with seperator) aggregate fonksiyonunun implementasyonu oluyor bu ornek. Bu arada MSSQL (T-SQL) built-in aggregate fonksiyonlara bakmak isterseniz lutfen buraya

using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;

[Serializable]
[SqlUserDefinedAggregate(
Format.UserDefined,
IsInvariantToNulls = true,
IsInvariantToDuplicates = false,
IsInvariantToOrder = false,
MaxByteSize = 8000)
]
public class Concatenate : IBinarySerialize
{
private StringBuilder intermediateResult;

public void Init()
{
this.intermediateResult = new StringBuilder();
}

public void Accumulate(SqlString value)
{
if (value.IsNull)
{
return;
}

this.intermediateResult.Append(value.Value).Append(',');
}

public void Merge(Concatenate other)
{
this.intermediateResult.Append(other.intermediateResult);
}

public SqlString Terminate()
{
string output = string.Empty;
if (this.intermediateResult != null
&& this.intermediateResult.Length > 0)
{
output = this.intermediateResult.ToString(0, this.intermediateResult.Length - 1);
}

return new SqlString(output);
}

public void Read(BinaryReader r)
{
intermediateResult = new StringBuilder(r.ReadString());
}

public void Write(BinaryWriter w)
{
w.Write(this.intermediateResult.ToString());
}
}

Sirasiyla gerceklememiz gereken metodlara bakalim. Aslinda bir constructor olarak dusunebileceginiz Init metodu ile sinifiniz icerisinde yer alan degiskenlerin ilk degerlerini verebilirsiniz. Accumulate metodu ise asil concat isleminin yapildigi yer. Kodtan da anlasilacagi uzere bos olmayan degerleri virgulle ayirarak output'a yaziyoruz. Terminate metodunda ise en son yapmak istediginiz islemleri yapabilirsiniz, ornegimizde en sondaki virgulu kaldirma islemi yapiliyor. Henuz bahsetmedigim merge metodu da iceriginden de anlasilacagi gibi birden fazla concatenate fonksiyonunun birbiri ile anlasmasini saglayacak metodtur.

Son olarak bir user defined aggregate tanimlamak icin sinifiniza 2 adet attribute(ozellik) eklemeniz gerekiyor. Bunlardan birincisi Serializable, digeri ise SqlUserDefinedAggregate. Burada SqlUserDefinedAggregate ozelligi icin bazi named parametre tanimlari goruyorsunuz. Zaten isimleri icerigini anlatiyor ancak diger parametre ve detaylar icin buraya bir goz atabilirsiniz.

Gelelim bu tanimladigimiz sinifimizi nasil SQL server'a tanitacagimiza.. Daha onceki CLRvsSQLServer yazilarimi okuduysaniz, yine oradakine benzer bir tanimlama kullanacagiz.


CREATE ASSEMBLY ClrCode FROM '<DLL_Path>'
GO
CREATE AGGREGATE Concatenate (@input nvarchar(200)) RETURNS nvarchar(max)
EXTERNAL NAME ClrCode.[ArticleCodes.Concatenate]

Herkeslere kolay gelsin...

 

Tags: , ,

C# | SQL

CLR User Defined Functions Part II

by Volem November 01, 2010 14:08

Daha onceki yazimda scalar deger donduren bir fonksiyonu nasil MSSQL Server'a tanittigimizi anlatmaya calismistim. Bu yazimda ise bir T-SQL'deki table-valued fonksiyonu CLR ile nasil tanimlayabilecegimizden bahsedecegim. Table-valued fonksiyonlar bildiginiz gibi bir data listesi seklinde (table) donus degeri olan fonksiyonlardir. Bunun Microsoft CLR karsiligi tahmin edebileceginiz gibi IEnumarable tipindedir. Fazla uzatmadan kod uzerinden anlatmaya calisacagim.


using System;
using System.Data.Sql;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Data.SqlClient;
using System.Data;


namespace ArticleCodes
{
    public class CLRTableValuedFunctions
    {
        private class CustomerResultMember
        {
            public SqlString Name { get; private set; }
            public SqlString Country { get; private set; }

            public CustomerResultMember(SqlString name, SqlString country)
            {
                Name = name;
                Country = country;
            }
        }

        [SqlFunction(FillRowMethodName = "FillRow",
            DataAccess = DataAccessKind.Read)]
        public static IEnumerable GetCompaniesSince(SqlDateTime creationDateStart)
        {
            ArrayList resultCollection = new ArrayList();
            using (SqlConnection conn = new SqlConnection("context connection=true"))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("SELECT Name, Country FROM Companies WHERE CreationDate >= @creationDateStart ", conn);
                SqlParameter creationDateParam = cmd.Parameters.Add(
                "@creationDateStart",
                SqlDbType.DateTime);
                creationDateParam.Value = creationDateStart;

                using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        resultCollection.Add(new CustomerResultMember(sdr.GetSqlString(0), sdr.GetSqlString(1)));
                    }
                }
                return resultCollection;
            }
        }

        public static void FillRow(object CustomerResultMemberObj, out SqlString customerName, out SqlString customerCountry)
        {
            CustomerResultMember crm = (CustomerResultMember)CustomerResultMemberObj;
            customerName = crm.Name;
            customerCountry = crm.Country;
        }
    }
}

Oncelik olarak asil isi yapan metodumuza bakalim.

public static IEnumerable GetCompaniesSince(SqlDateTime creationDateStart)

Bu metod gordugunuz gibi IEnumerable donduren ve ayni scalar fonksiyon tanimindaki gibi (bkz. onceki makale) statik bir metod. Kisaca ArrayList icerisine Select metodu ile belirlenmis ve metod parametresiyle sinirlanmis verileri ekleyip, bu ArrayList'i donduruyor. CLR tanimlamak icin daha once de belirttigim gibi belirli standartlar var. Scalar fonksiyon taniminda iki adet standart tanim yapmaniz gerekiyor, bunlar 1 adet init metod ve bu metodun fillrow metodudur. Init metodu, yani bizim ornegimizde GetCompaniesSince datayi getiren ve isi yapan metoddur. FillRow ise IEnumarable'dan anlamaya SQL server'a bu datayi nasil isleyebilecegini gosteren metoddur. Cunku artik olusacak fonksiyon diger T-SQL query'leri icinde de bir tabloymuscasina kullanabilir. Sonucta konumuz tablo donen fonksiyonlar Smile.

Dikkat edilmesi gereken husus, sadece init metodunuzun icerisinde bir sql connection yapabilirsiniz ancak FillRow metodunda bunu yapamazsiniz. Init metodunda da bunu yapabilmek icin SqlFunction attributenun DataAccess parametresi DataAccessKind.Read seklinde set edilmesi gerekmektedir.

Son olarak bu yeni CLR metodumuzu SQL server'a nasil tanitacagimiz konusu kaldi. Daha onceki yazimda bu tanimlamada yapilan isin detaylari bulabilirsiniz. Burada tekrar etmeden sadece kodu veriyorum.


CREATE ASSEMBLY ClrCode FROM '<DLL_Path>'
WITH PERMISSION_SET = SAFE -- EXTERNAL_ACCESS
GO

CREATE FUNCTION GetCompaniesSince(@CreationDate datetime)
RETURNS TABLE (
   Name nvarchar(50),
   Country nvarchar(50)
)
AS EXTERNAL NAME ClrCode.[ArticleCodes.CLRTableValuedFunctions].GetCompaniesSince

Herkese iyi calismalar.

Tags: , ,

C# | SQL

CLR User Defined Functions Part I

by Volem October 25, 2010 10:12

Microsoft teknolojilerinin ne kadar icli disli oldugunu biliyorsunuzdur. Ornegin siz bir web uygulamasinin icinde Excel sheet, windows uygulamasinin icinde explorer nesnesini cok da ugrasmadan kullanabilirsiniz. Bu iliskiye benzer bir iliski ile C# veya VB.NET de yazdiginiz bir metodu bir MS SQL Server fonksiyonuna nasil cevirebilirsiniz sorusunu yanitlamaya calisacagim. Bu 3 alt makaleden olusan yazi dizisinin 1.si..

Microsoft SQL 2005 Server'dan itibaren CLR(Common Language Runtime) User defined functions (kullanici tanimli fonksiyonlar) tanimlamamiza izin veriyor. Bu yazimda oncelikli olarak size scalar bir deger donduren bir fonksiyonu sql server'a nasil tanitacagimizi anlatmaya calisacagim.

Oncelikle C# kodumuza bir goz atalim..

using System.Data.SqlClient;
using Microsoft.SqlServer.Server;

namespace ArticleCodes
{
    public class CLRScalarValuedFunction
    {
        [SqlFunction(DataAccess=DataAccessKind.Read)]
        public static int GetCompanyCount()
        {
            using (SqlConnection conn = new SqlConnection("context connection=true"))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("SELECT COUNT(*) AS companyCount FROM Companies", conn);
                return (int)cmd.ExecuteScalar();
            }
        }
    }
}

Bir scalar fonksiyon tanimlamak icin oncelikle metodumuzun static bir metod olmasi gerekiyor. Yukaridaki kod kendini anlatiyor diye dusunuyorum. Burada dikkatinizi cekmek istedigim kisim SqlConnection tanimi.. Dikkat ederseniz alisila gelmis connection string'lerden biraz farkli.

SqlConnection conn = new SqlConnection("context connection=true")

Peki neden boyle bir tanim yaptik ve bu tanim bize ne anlatiyor. Oncelikli olarak biz bu metodu SQL Server'a tanitacagiz ve bu bir veritabanina ya da master'a tanimli olacaktir. Dolayisiyla metodu kullanacak olan kisi zaten bir veritabani baglantisi yapacak ve ardindan bizim metodumuzu kullanacaktir. Biz iste bu baglantidaki yetkileri ile bu metodu cagiriyoruz. Dolayisiyla guvenli bir baglanti yapiyoruz. Eger bu metodu cagirma ya da bu veritabanina baglanma ve yahut da veri cekme yetkisi yok ise bu kontrolleri yapmamiza gerek kalmiyor. Context Connection ile ilgili detayli bilgi icin buraya bi goz atabilirsiniz.

Bunun disinda dikkat etmemiz gereken husus metodumuzun giris parametreleri ve donus degeridir. Bunlarin SQL Server tarafindan desteklenen scalar deger tipleri olmasi gerekiyor. Bu konuda da suraya bi bakin derim.

Simdi gelelim bu yazdigimiz ve derledigimiz metodu nasil SQL Server'a tanitacagimiza..

CREATE ASSEMBLY CLRCodes FROM '<DLL'in tam yolu(full path)>'

Bu T-SQL komutunu metodumuzu tanimlamak istedigimiz veritabanimizda calistiriyoruz. Boylece tanimladigimiz dll artik SQL server tarafindan benimsenmis oluyor. Ardindan yapilacak ikinci iş, metodumuzu tanimlamak..

CREATE FUNCTION GetCompanyCount() RETURNS INT
AS EXTERNAL NAME <assembly adi>.[<namespace>.<class adi>].<method adi>

Yani verdigim ornege gore

CREATE FUNCTION GetCompanyCount() RETURNS INT
AS EXTERNAL NAME CLRCodes.[ArticleCodes.CLRScalarValuedFunction].GetCompanyCount

Bu komutlari calistirdiktan sonra goreceksiniz ki assembly altinda CLRCodes adinda bir dll ve Scalar-Valued functions altinda GetCompanyCount adinda bir metod olusturulmustur. Metodu test etmek icin

SELECT [dbo].[GetCompanyCount]()

querisini calistirabilirsiniz.

Ancak kodu test ettiginizde muhtemelen "CLR not enabled" benzeri bir hata alacaksiniz. Buradan da sunu cikariyoruz; SQL Server default olarak sizin .NET kodunuzu desteklemiyor. Bunu desteklemek icin ise asagidaki kodu calistirabilirsiniz.

EXEC sp_configure 'clr enabled' , '1'
go
reconfigure;
go

Umarim isinize yarar...

Tags: , ,

C# | SQL

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen | Modified by Volem

RSS
View Volkan Nazmi Metin's profile on LinkedIn

RevolverMap

Son Eklenen Yazılar

Yazar Hakkında

Sosyal, evli, çocuklu, karısını ve kızını çok seven, gezmeyi seven, spor yapmak isteyen bir mühendis