C# : Basit ama kullanışlı metotlar
Bu yazıda zamanla geliştirdiğim bazı basit ama çok kullanışlı metotları paylaşacağım. Bu metotları kullanarak uygulamalarınızı daha modüler hale getirebilir ve zaman kazanabilirsiniz. Bu metotları bir sınıf içinde toplayarak uygulamanıza dahil edin ve her kullandığızda bana bir teşekkürü çok görmeyin. :)
Tüm metotları içeren sınıfı
buradan indirebilirsiniz. Keyfini çıkarın.
1. İki byte[] array'in karşılaştırılması/// <summary>
/// İki byte[] array'in aynı diziler olup olmadığını kıyaslar.
/// </summary>
/// <param name="hash1">ilk byte[] array.</param>
/// <param name="hash2">ikinci byte[] array.</param>
/// <returns>diziler eşitse true, değilse false</returns>
public static bool IsEqualArray(byte[] hash1, byte[] hash2)
{
bool isEqual = false;
if (hash1.Length == hash2.Length)
{
int i = 0;
while ((i < hash1.Length) && (hash1[i] == hash2[i]))
{
i += 1;
}
if (i == hash1.Length)
{
isEqual = true;
}
}
return isEqual;
}
2. MD5CryptoServiceProvider kullanarak metin şifreleme/// <summary>
/// Verilen metni MD5CryptoServiceProvider ile şifreleyerek byte[] dizinine döndürür.
/// </summary>
/// <param name="str">Şifrelenecek metin.</param>
/// <returns>byte[]</returns>
public static byte[] Crypt(string str)
{
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
byte[] hashedBytes;
UTF8Encoding encoder = new UTF8Encoding();
hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(str));
return hashedBytes;
}
3. Email kontrolü (sunucu taraflı) /// <summary>
/// Verilen değerin geçerli bir email adresi olup olmadığını sınar.
/// </summary>
/// <param name="strEmail">Email adresi</param>
/// <returns>bool</returns>
public static bool IsEmail(string strEmail)
{
string regex_Email = @"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$";
Regex re = new Regex(regex_Email);
return re.IsMatch(strEmail) ? true : false;
}
4. Guid (Unique Identifier) kontrolü (sunucu taraflı)/// <summary>
/// Verilen değerin Guid olup olmadığını kontrol eder.
/// </summary>
/// <param name="strGuid">guid değeri</param>
/// <returns>bool</returns>
public static bool IsGuid(string strGuid)
{
string regex_Guid = @"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$";
bool isValid = false;
if (!String.IsNullOrEmpty(strGuid))
{
Regex re = new Regex(regex_Guid);
if (re.IsMatch(strGuid))
{
isValid = true;
}
}
return isValid;
}
5. Html encode/// <summary>
/// html şifreleme işlemi gerçekleştirir.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string HtmlEncode(string str)
{
return System.Web.HttpUtility.HtmlEncode(str);
}
6. Html decode/// <summary>
/// şifrelenmiş bir html metni çözer.
/// </summary>
/// <param name="strEncoded"></param>
/// <returns></returns>
public static string HtmlDecode(string strEncoded)
{
return System.Web.HttpUtility.HtmlDecode(strEncoded);
}
Microsoft .Net Framework 3.5 İncelemesi : C# 3.0 ve VB 9.0 dil geliştirmeleri
Microsoft .Net Framework 3.5, beraberinde bir sürü iyileştirme ve yeni dil özellikleri getiriyor. Bu yazıda an itibarıyla yayınlanan Beta 2 sürümü ile gelen özellikleri inceleyeceğiz. Microsoft .NET Framework 3.5 Beta 2 sürümü
bu adresten indirilebilir.
İnceleyeceğimiz özellikler:
1. Automatic Properties
2. Object Initializers
3. Collection Initializers
4. Extension Methods1. Automatic PropertiesAutomatic Properties (otomatik özellikler), uygulamalarımızda kullandığımız sınıfların (class) tanımlamalarında bize kolaylık sağlayan bir geliştirmedir. Bu geliştirme sayesinde private field'lar tanımlamadan property'lerimizi tanımlayabilir ve kullanabiliriz. Hemen örnekle açıklayalım. .Net 2.0 altında yazılmış bir Student sınıfımız olsun :
public class Student
{
private string name;
private string surname;
private int age;
private string studentNumber;
public string Name
{
get { return name; }
set { name = value; }
}
public string Surname
{
get { return surname; }
set { surname = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public string StudentNumber
{
get { return studentNumber; }
set { studentNumber = value; }
}
}
Görüldüğü gibi dört farklı property tanımlayabilmek için boşlukları saymazsak tam 27 satır kod yazdık. Bu sınıf .Net 3.5 altında Automatic Properties sayesinde şöyle yazılabilir :
public class Student
{
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
public string StudentNumber { get; set; }
}
Aynı sınıfı sadece 7 satır kod ile yeniden yazdık. Satır sayısının 27'den 7'ye indiğine dikkat edin.
.Net 3.5 C# derleyicisi bu şekilde tanımlanmış bir sınıf gördüğünde private field'leri bizim için otomatik olarak tanımlamakta ve ilgili public property'ler ile ilişkilendirmektedir. Yani kısaca, bir sınıf tanımlarken artık sadece property'leri tanımlamak yeterlidir. 30 küsur property içeren bir sınıf tanımladığınızda Automatic Property özelliğini çok seveceksiniz.
Bu özellik sadece C# derleyicisinde geçerlidir.
2. Object InitializersBir önceki örneğimizde tanımladığımız Student sınıfımızı kullanarak yeni bir Student objesi yaratalım. .NET 2.0 altında ilgili kod aşağıdaki gibi olmalıdır :
Student std1 = new Student();
std1.Name = "Ahmet";
std1.Surname = "Demir";
std1.Age = 19;
std1.StudentNumber = "8935";
Student std2 = new Student();
std2.Name = "Mehmet";
std2.Surname = "Yılmaz";
std2.Age = 18;
std2.StudentNumber = "3252";
Aynı işlevi gören kodu .NET 3.5 altında şöyle yazabiliriz:
Student std1 = new Student {Name="Ahmet", Surname = "Demir", Age = 19, StudentNumber = "8935"};
Student std2 = new Student {Name="Mehmet", Surname = "Yılmaz", Age = 18, StudentNumber = "3252"};
Bu özellik hem C# hem de VB derleyicilerinde geçerlidir.
3. Collection InitializersYine Student sınıfımızdan yola çıkarak şöyle bir senaryo geliştirelim. İki farklı öğrencinin bilgilerini tutan bir Generic List oluşturalım. Oluşturduğumuz bu List<Student>'i öğrenci bilgilerini kaydetmek veya güncellemek için kullanabiliriz.
.Net 2.0 altında List<Student> generic listemizi oluşturalım :
Student std1 = new Student();
std1.Name = "Ahmet";
std1.Surname = "Demir";
std1.Age = 19;
std1.StudentNumber = "8935";
Student std2 = new Student();
std2.Name = "Mehmet";
std2.Surname = "Yılmaz";
std2.Age = 18;
std2.StudentNumber = "3252";
List<Student> studentList = new List<Student>();
studentList.Add(std1);
studentList.Add(std2);
.....
.Net 3.5 altında aynı işlevi gerçekleştirelim :
List<Student> studentList = new List<Student> {
new Student {Name="Ahmet", Surname = "Demir", Age = 19, StudentNumber = "8935"},
new Student {Name="Mehmet", Surname = "Yılmaz", Age = 18, StudentNumber = "3252"}
};
Bu özellik hem C# hem de VB derleyicilerinde geçerlidir.
4. Extension MethodsExtension Methods, mevcut bir sınıfımızı, sınıfı oluşturan kod üzerinde hiçbir değişiklik yapmadan extend etmemize (geliştirmemize) yarayan çok kullanışlı bir geliştirmedir. Bir Extension method, mevcut bir CLR tipi üzerinde işlem yapmaya yarayan static bir metotdur. Ayrıca tüm extension metotları yine static tanımlanan bir sınıf içerisinde olmalıdır.
Hemen bir örnekle açıklayalım: Uygulamamız içinde vergi hesaplamaları yaptığımızı varsayalım. GetTaxNumber adında bir metodumuz olsun ve bu metot kendi içinde özel hesaplamalar yaparak aylık vergi tutarını döndürsün.
public static class CustomExtensionMethods
{
public static decimal GetTaxNumber(this int number)
{
decimal tax = 0.18M;
return (number * tax / 12);
}
}
Tanımladığımız metodumuzu kullanalım :
using CustomExtensionMethods;
public partial class testclass()
{
private void test()
{
int salary = 1000;
decimal taxMonthly = salary.GetTaxNumber();
}
}
Bu özellik hem C# hem de VB derleyicilerinde geçerlidir.
Bu yazıda Microsoft Net Framework 3.5'un yazılım dünyasına getirdiği yenilikleri ele aldık. Şüphesiz geliştirmeler sadece bunlarla sınırlı değil.
Implicitly typed local variables, Anonymous Types, Lambda expressions, Query expressions, Expression Trees gibi diğer önemli geliştirmeleri başka bir yazıda inceleyeceğiz.
C# : Efektif string birleştirme teknikleri
Bu yazı .net framework altında etkili string birleştirme yöntemlerine değinmektedir.Bildiğiniz gibi String değişkeni yazılımlarımızda çok sık kullandığımız veri tiplerimizden bir tanesidir. .Net Framework, System.Text uzayı (namespace) altında barındırdığı sınıflarla (class) string işlemlerine zengin bir destek sağlar.
System.Text altındaki sınıfların ayrıntılarına
buradan erişebilirsiniz. Mutlaka göz atmanızı tavsiye ediyorum.
Asıl konumuza gelince, bazen yazılımlarımız içerisinde farklı değişkenleri birleştirerek text çıktıları oluşturmamız gerekir. Örneğin, uygulamanızın ürettiği hataları yakalayarak ayrıntılarını bir log dosyasına yazdırmak isteyebilirsiniz. Bu durumda uygulamanız oluşan hatayı yakalamalı ve hata nesnesinin tüm özelliklerini bir metin haline getirerek log dosyasına yazmalıdır. (ayrıca satır satır veri yazma işlemi yapmak da mümkündür; fakat konumuz string birleştirme yöntemlerinin performasını irdelemek olduğu için verinin birleştirilerek yazılması esas alınmıştır.)
Bu yazıda 3 farklı yöntemi inceleyeceğiz ve test edeceğiz.
- "+" yöntemi ile birleştirme
- System.Text.StringBuilder sınıfı ile birleştirme
- System.Collections.Generic.List Generic sınıfı ile birleştirme
1. "+" yöntemi ile birleştirme.Bu metod string değişkenlerinin + operatörü ile birbiri ardına eklenmesi esasına dayanır.
// iki farklı değişken birleştirilmiştir.
string strFirstName = "Cihan";
string strLastName = "Uçar";
string strName = strFirstName + " " + strLastName;
// aynı değişkene yeni veri eklenmektedir.
string myMessage = "Merhaba ";
myMessage = myMessage + "Dünya. "; // + ile ekleniyor. (Kötünün kötüsü kod.)
myMessage += "Küresel ısınma dünyanın sonu mu?"; // += ile ekleniyor.
myMessage += "Buzullar eriyor, sular yükseliyor.";
Bu yönteme dair görüşümü çok net belirtmek istiyorum:
Bu yöntemi unutun, hafızanızdan kazıyın! Bu yöntem string birleştirme işlemleri için
son derece kötü ve performans düşürücü bir yöntemdir. Bu yöntemdeki dezavantaj şudur :
String objesi immutable (değişmeyen) bir objedir ve siz her seferinde + ile yeni bir string eklediğinizde mevcut string'iniz yeni bir objeye atanmaktadır. Satır satır açıklamak gerekirse :
string myMessage = "Merhaba ";
myMessage objesi ilk defa yaratıldı ve "Merhaba" değeri atandı.
myMessage = myMessage + "Dünya. ";
Opsss.. myMessage objesi tekrar yaratıldı. myMessage'ın ilk tanımlı değeri ile "Dünya" birleştirilerek myMessage'e atanmıştır. myMessage ikinci kere tanımlandı.
myMessage += "Küresel ısınma dünyanın sonu mu?"; // += ile ekleniyor.
Opsss.. Aynı şekilde myMessage tekrar tanımlandı.
.....
Sonuç olarak her yeni atamada tekrar tekrar yeni bir obje yaratılmaktadır. Ne kadar çok obje yaratılıyorsa o kadar çok kaynak tüketimi gerçekleşir. Bu yöntemin handikapı buradan kaynaklanmaktadır. Küçük çaplı stringleri birleştirirken (ki yine de önermiyorum) bu yöntem nispeten kabul edilebilirken, büyük çaplı string birleştirmelerde asla ama asla kullanılmamalıdır.
2. System.Text.StringBuilder sınıfı ile birleştirmeStringBuilder sınıfı string işlemleri için iyi derecede optimize edilmiş çok kullanışlı bir sınıftır. Bu sınıfı kullanarak oldukça hızlı string manipülasyonları gerçekleştirebiliriz.
Kullanımı şu şekildedir :
using System.Text;
.....
StringBuilder sb = new StringBuilder();
sb.Append("Merhaba ");
sb.Append("Dünya.");
sb.Append("Küresel ısınma dünyanın sonu mu?");
sb.Append("Uydurma metin...");
string myMessage = sb.ToString();
Kullanımı çok basit olan StringBuilder sınıfının ToString metodu ile birleştirilmiş metne erişebilirsiniz.
Bu yöntem çok sayıda string'in birleştirilmesi esnasında kullanılırsa büyük performans sağlar. Genel teori açısından 2 veya daha fazla birleştirme işlemi yapacaksanız önerim bu sınıfı kullanmanız.
3. System.Collections.Generic.List Generic sınıfı ile birleştirmeGenerics kavramına ucundan bulaşmamışsanız bu yöntemi boşverin. (Ben bilmiyorum ama kasıcam öğrenicem diyen azimli gençleri şuraya alalım. Azminizi takdir ettiğimi de ayrıca belirtmek isterim.)Yönteme geçmeden önce .Net framework 2.0 ile gelen özelliklerden birisi olan Generics'e biraz değinmek istiyorum. Generics kod kullanılabilirliğinin arttırılması, performans iyileştirmeleri, koleksiyon sınıfları (collection classes) oluşturulması gibi özellikler sunan bir yapıdır. Teorik olarak anlaşılması zor olmakla birlikte inceleyeceğiniz örnek kodlarla yapıya daha aşina olacağınızı düşünüyorum.
Konumuza dönelim ve string birleştirmelerinin List Generic sınıfı ile nasıl yapıldığını görelim.
using System.Collections.Generic;
........
List<string> list = new List<string>();
list.Add("Merhaba ");
list.Add("Dünya. ");
list.Add("Küresel ısınma dünyanın sonu mu?");
list.Add("Uydurma metin...");
string myMessage = String.Join(String.Empty, list.ToArray());
Örnekte, string tipinde bir generic list oluşturulmuş ve değerler eklenmiştir. ( Aklıma gelmişken System.Collections.Generic.List sınıfının ArrayList sınıfının generic versiyonu olduğunu belirteyim. ) Daha sonra liste değerler array haline dönüştürülerek String.Join metodu ile birleştirilmiştir.
Bu yöntem de oldukça performanslı bir şekilde string birleştirmeye yarar.
Yukarıdaki metotları test etmek için ufak bir uygulama yazdım. Ekran görüntüsü aşağıdaki gibidir :

Arayüz çok basit ve anlaşılır olduğu için ayrıntılara girmiyorum ama uygulamanın test kriterlerini özellikle açıklamak istiyorum.

Yazının başında belirttiğim örneği canlandırabilmek için yandaki hata sınıfını yazdım. (ErrorHandler.cs) Şüphesiz bu sınıf gerçek bir hata yakalama sınıfı olmaktan öte test amaçlı yazılmış basit bir sınıftır.
Uygulama kodunu incelerseniz property'lerin varsayılan değerleri olduğunu göreceksiniz. Bunu sadece kolay test verisi üretmek adına yaptım.
Yöntemi test etmek için ilgili butona tıkladığınızda yeni bir ErrorHandler objesi yaratılmakta ve o yöntemi kullanarak ErrorHandler property'leri birleştirilerek tek bir string oluşturulmaktadır. (log dosyası yazılabilir, email atılabilir vs. ) Bu işlem yöntemlerin performans farkı insani açıdan fark edilebilir sürelerde olması için 1000 kere tekrarlanmaktadır.
Yaptığım bir test sonucunu göstermek istiyorum :

Sonuçlar şaka gibi değil mi? Dediğim gibi siz siz olun ilk yöntemi kullanmayın. İkinci ve üçüncü yöntemlerin süreleri çoğu zaman birbirine yakınken ilk yöntem onların yanına asla yaklaşamamaktadır.
Test uygulamasını
buradan indirebilirsiniz.
"Hızlı" kalın.
Enumeration kullanımı ve kolaylıklar
Enumeration (numaralama), programlar içinde oluşturduğumuz değerlere anlamlı isimler vermemizi sağlayan faydalı bir yapıdır. Yazılan kodu anlaşılır kılar ve programcıya büyük kolaylık sağlar.
C# dilinde enumeration tanımlamak aşağıdaki gibidir :
// kullanıcı işlemleri metotlarından dönen sonuç tipleri
public enum UserProcessResult
{
UserCreated = 0, // kullanıcı başarıyla oluşturuldu.
UserCouldntCreate = 1, // işlem sonucu hata oluştu. Kullanıcı oluşturulmadı.
IncompleteData = 2, // kullanıcı oluşturmak için zorunlu olan alanlar eksik.
InvalidData = 3, // hatalı veri. (Geçersiz email adresi vs.)
UserNotFound = 4 // sistemde aranan kullanıcı mevcut değil.
}
Bu örnekte sistemde yer alan bir kullanıcı üzerinde yapılabilecek işlemlerin sonuçları UserProcessResult yapısı içinde tutulmaktadır. Böylece kullanıcı üzerinde işlem yapan veri katmanında dönen sonuçlar ile tanımladığımız yapı kıyaslanarak işlemlere yön verilebilir.
Yine kodla açıklarsak :
// Bir üyelik formu doldurduğunu ve üye olmak istediğini varsayalım.
// kullanıcıdan form bilgileri alınır ve sisteme kaydedilir.
// CreateUser kullanıcı yaratan metodumuz olsun.
int result; // işlem sonucunu tutmak için değişken
result = CreateUser(username,password, useremail);
switch (result)
{
case (int)UserProcessResult.UserCreated :
// işlem başarılı :)
Response.Redirect("/yasasinislembasarili.aspx",true);
break;
case (int)UserProcessResult.IncompleteData :
lblMessage.Text = "Eksik bilgi girdiniz. Lütfen tüm zorunlu alanları doldurun ve tekrar deneyin.";
PanelErrorLog.Visible = true;
break;
case (int)UserProcessResult.UserCouldntCreate:
lblMessage.Text = "İşlem esnasında bir hata oluştu ve bilgileriniz kaydedilmedi. Lütfen tekrar deneyin.";
PanelErrorLog.Visible = true;
break;
}
Gördüğünüz gibi anlamlı kod parçacıkları üretmek için enumeration büyük kolaylık sağlamaktadır.
Bu arada enumerationların tanımlanırken
herhangi bir değer atanmadan da tanımlanabileceğini belirteyim. Aşağıdaki ifade de geçerli bir tanımlamadır ve değerler
otomatik olarak sıfırdan başlayarak atanır. Bu şekilde enumeration tanımlanması kod içinde karmaşıklığa yol açağı için mutlaka ve mutlaka
kendi tanımladığınız değerleri atayarak tanımlama yapmanızı öneriyorum.
public enum UserProcessResult
{
UserCreated,
UserCouldntCreate,
IncompleteData,
InvalidData,
UserNotFound
}
Enumeration'ları public olarak tanımlayıp static bir class'ın içine koyarsanız tüm projeniz kapsamında paylaşabilir ve kolaylıkla kullanabilirsiniz.
MS Sql Server saklı yordamlarına (stored procedure) çoklu parametre geçmek
Bu yazıda Microsoft Sql Server ™ üzerinde yazılmış prosedürlere (stored procedure) çoklu parametre geçmenin yollarından birini inceleyeceğiz. T-Sql diline ve temel programcılık bilgisine hakim değilseniz bu yazı sizin için karmaşık olabilir.
Bildiğimiz gibi Microsoft Sql Server en yeni sürümü olan 2005 dahil olmak üzere bütünleşik bir dizi (array) desteği getirmemektedir. Bu nedenle veriyle iletişimizi sağlayan prosedürlerimizde dizi veya benzeri bir veri tipini kullanmamız mümkün değil. Böyle olmasaydı uygulamamız içinde yaratacağımız diziyi prosedürümüze geçer ve bu yazıyı okumak yerine arkamıza yaslanır tv izlerdik. Bu yazıda bu zorluğu aşmak için xml metodunun nasıl kullanılacağını göstereceğim.
Vaktiyle üzerinde çalıştığım bir emlak portalı projesinde, kullanıcılara seçtikleri ilanları kıyaslamalarını sağlayabilecek bir sistem geliştiriyordum. Kullanıcı sınırsız sayıda ilan seçebilecek ve seçtiği ilanların tüm detayları veritabanından alınarak birebir kıyaslanacaktı. Bu durumda daha önce yazmış olduğum ve sadece bir ilana ait üm detayları getiren prosedür yeterli olmayacaktı.
Elimdeki mevcut prosedür şöyleydi :
CREATE PROCEDURE [dbo].[SelectAdvertisement]
(@AdvertisementIndex bigint,
.... )
AS ....
Bu prosedürü baz alarak şu şekilde yeni bir tane yazdım :CREATE PROCEDURE [dbo].[SelectAdvertisementMultiple]
(
@AdvertisementIndexListXml varchar(1000)
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @DocXml int
EXEC sp_xml_preparedocument @DocXml OUTPUT, @AdvertisementIndexListXml
SELECT * FROM dbo.Advertisements AS a WITH (NOLOCK) INNER JOIN
OPENXML (@DocXml, '/advertisementlist/adv', 1) WITH (AdvertisementIndex int) AS b
ON a.AdvertisementIndex = b.AdvertisementIndex
WHERE a.Active=1
EXEC sp_xml_removedocument @DocXml
END
Prosedürün çalıştırılması ise şöyle olmalı :
EXEC dbo.[SelectAdvertisementMultiple]
'<advertisementlist>
<adv advertisementindex="24343" />
<adv advertisementindex="536332" />
<adv advertisementindex="72224" />
</advertisementlist>
'
Gördüğünüz gibi geçeceğimiz parametreleri bir xml metin haline getirip prosedüre geçiyoruz.
Prosedür aldığı xml metni OPENXML ile parse ederek (parse : işlemek, ayrıştırmak) AdvertisementIndex'leri ayrıştırmakta ve ayrıştırılan AdvertisementIndex'ler inner join ile ilgili tabloyla eşlenmektedir.
OPENXML ile ilgili ayrıntılar için
http://technet.microsoft.com/en-us/library/ms186918.aspx
adresini ziyaret edebilirsiniz.Uygulamanız içerisinden Xml oluşturmak için .NET classlarını kullanabilirsiniz. System.Xml altında bulunan classları başka bir yazıda ayrıntılı olarak anlatacağım.
Yine de konuyu tamamlamak açısından uygulama tarafında basit bir örnek vermek istiyorum :
using System.Xml ; // Xml sınıflarını (class) barındıran namespace (uzay)
............
private long[] AdvertisementIndexList = new long[5];
// kullanıcıdan gelen ilan idleri al, işle ve AdvertisementIndexList dizisine al.
// bu yazıyı okuduğunuza göre bu kısmı kodlamak sizin için çocuk işi :).
.............
XmlDocument xmldoc = new XmlDocument();
XmlNode advertisementListNode = xmldoc.CreateElement("AdvertisementList");
xmldoc.AppendChild(advertisementListNode);
for (int i = 0; i < this.AdvertisementIndexList.Length; i++)
{
XmlNode advNode = xmldoc.CreateElement("Adv");
XmlAttribute advNodeAttribute = xmldoc.CreateAttribute("AdvertisementIndex");
advNodeAttribute.Value = this.AdvertisementIndexList[i].ToString();
advNode.Attributes.Append(advNodeAttribute);
advertisementListNode.AppendChild(advNode);
}
string xmlString = xmldoc.InnerXml;
.....
// bağlantı (connection), komut (command) objelerini oluştur..
// xml komut objesine ekle.
cmd.Parameters.Add("@AdvertisementIndexListXml", SqlDbType.VarChar,1000).Value = xmlString;
.......
// örnekte data reader kullanıyorum ama DataSet de kullanabilirsiniz.
SqlDataReader reader = cmd.ExecuteReader();
Gördüğünüz gibi esasında xml yöntemi ile prosedürlere "dizi" geçmek oldukça kolay. Farklı yöntemler de mevcut olmasına rağmen , kişisel olarak bu yöntemi kullanıyorum.
Diğer yöntemlere gelince :
1- Dinamik sql kullanmak. (Yanlış kullanım sql injection davetiyesi çıkarır.)
2- Diziyi CSV formatına getirip prosedüre geçmek ve "123,456,789,743,244,4223" şeklindeki veriyi işlemek.
3-Yukarıdaki işleme işini yapan ve tablo tipi veri döndüren bir UDF (user defined function : kullanıcı tanımlı fonksiyon) yazmak. Prosedürümüzü table veri tipi alır hale getirmek ve UDF'in çıktısını prosedüre vermek.
Xml'i tercih ettiğimi tekrarlıyorum.