LINQ ile Veri Dönüştürmeler (C#)
Language-Integrated (LINQ) yalnızca veri almakla ilgili değildir. Ayrıca verileri dönüştürmek için güçlü bir araçtır. LINQ sorgusu kullanarak, giriş olarak bir kaynak dizi kullanabilir ve bunu birçok şekilde değiştirerek yeni bir çıkış dizisi oluşturabilirsiniz. Sıralama ve gruplama ile öğelerin kendisini değiştirmeden sıranın kendisini değiştirebilirsiniz. Ancak LINQ sorgularının belki de en güçlü özelliği yeni türler oluşturabilme özelliğidir. Bu, select yan tümcesinde başarılı olur. Örneğin, aşağıdaki görevleri gerçekleştirebilirsiniz:
Birden çok giriş dizisini yeni türü olan tek bir çıkış dizisiyle birleştirin.
Öğeleri kaynak dizideki her öğenin yalnızca bir veya birden fazla özelliğine sahip olan çıkış dizileri oluşturun.
Öğeleri kaynak verilerde gerçekleştirilen işlemlerin sonuçlarından oluşan çıkış dizileri oluşturun.
Çıkış dizilerini farklı bir biçimde oluşturun. Örneğin, verileri satırlardan veya metin SQL XML'ye dönüştürebilirsiniz.
Bunlar yalnızca birkaç örnektir. Elbette bu dönüştürmeler aynı sorguda çeşitli şekillerde bir araya yapılabilir. Ayrıca, yeni bir sorgunun giriş dizisi olarak bir sorgunun çıkış dizisi kullanılabilir.
Birden Çok Girdiyi Bir Çıkış Sırasına Katma
LinQ sorgusu kullanarak birden fazla giriş dizisini içeren öğeler içeren bir çıkış dizisi oluşturabilirsiniz. Aşağıdaki örnekte iki bellek içinde veri yapısının nasıl birleştirildiklerinden biri gösterir, ancak XML veya SQL veya DataSet kaynaklarından verileri birleştirmek için aynı ilkeler uygulanabilir. Aşağıdaki iki sınıf türü olduğunu varsayalım:
class Student
{
public string First { get; set; }
public string Last {get; set;}
public int ID { get; set; }
public string Street { get; set; }
public string City { get; set; }
public List<int> Scores;
}
class Teacher
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public string City { get; set; }
}
Aşağıdaki örnekte sorguyu gösterir:
class DataTransformations
{
static void Main()
{
// Create the first data source.
List<Student> students = new List<Student>()
{
new Student { First="Svetlana",
Last="Omelchenko",
ID=111,
Street="123 Main Street",
City="Seattle",
Scores= new List<int> { 97, 92, 81, 60 } },
new Student { First="Claire",
Last="O’Donnell",
ID=112,
Street="124 Main Street",
City="Redmond",
Scores= new List<int> { 75, 84, 91, 39 } },
new Student { First="Sven",
Last="Mortensen",
ID=113,
Street="125 Main Street",
City="Lake City",
Scores= new List<int> { 88, 94, 65, 91 } },
};
// Create the second data source.
List<Teacher> teachers = new List<Teacher>()
{
new Teacher { First="Ann", Last="Beebe", ID=945, City="Seattle" },
new Teacher { First="Alex", Last="Robinson", ID=956, City="Redmond" },
new Teacher { First="Michiyo", Last="Sato", ID=972, City="Tacoma" }
};
// Create the query.
var peopleInSeattle = (from student in students
where student.City == "Seattle"
select student.Last)
.Concat(from teacher in teachers
where teacher.City == "Seattle"
select teacher.Last);
Console.WriteLine("The following students and teachers live in Seattle:");
// Execute the query.
foreach (var person in peopleInSeattle)
{
Console.WriteLine(person);
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
The following students and teachers live in Seattle:
Omelchenko
Beebe
*/
Daha fazla bilgi için bkz. join yan tümcesi ve select yan tümcesi.
Her Kaynak Öğesinin alt kümesini seçme
Kaynak dizideki her öğenin bir alt kümesini seçmenin iki birincil yolu vardır:
Kaynak öğenin yalnızca bir üyesini seçmek için nokta işlemi kullanın. Aşağıdaki örnekte, bir nesnenin adlı dize
Customerdahil olmak üzere birkaç genel özellik içerdiğini varsayalım.CityYürütülürken, bu sorgu dizelerden bir çıkış dizisi oluşturur.var query = from cust in Customers select cust.City;Kaynak öğesinden birden fazla özellik içeren öğeler oluşturmak için, adlandırılmış bir nesne veya anonim tür ile bir nesne başlatıcı kullanabilirsiniz. Aşağıdaki örnek, her bir öğeden iki özelliği kapsülleyen anonim bir türün kullanımını
Customergösterir:var query = from cust in Customer select new {Name = cust.Name, City = cust.City};
Daha fazla bilgi için bkz. Nesne ve Koleksiyon Başlatıcıları ve Anonim Türler.
Bellek İçi Nesneleri XML'e dönüştürme
LINQ sorguları, verileri bellek içinde veri yapıları, SQL veritabanları, ADO.NET veri kümeleri ve XML akışları veya belgeleri arasında dönüştürmeyi kolaylaştırır. Aşağıdaki örnek, bellek içinde veri yapısında yer alan nesneleri XML öğelerine dönüştürer.
class XMLTransform
{
static void Main()
{
// Create the data source by using a collection initializer.
// The Student class was defined previously in this topic.
List<Student> students = new List<Student>()
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}},
new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
};
// Create the query.
var studentsToXML = new XElement("Root",
from student in students
let scores = string.Join(",", student.Scores)
select new XElement("student",
new XElement("First", student.First),
new XElement("Last", student.Last),
new XElement("Scores", scores)
) // end "student"
); // end "Root"
// Execute the query.
Console.WriteLine(studentsToXML);
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
Kod aşağıdaki XML çıkışını üretir:
<Root>
<student>
<First>Svetlana</First>
<Last>Omelchenko</Last>
<Scores>97,92,81,60</Scores>
</student>
<student>
<First>Claire</First>
<Last>O'Donnell</Last>
<Scores>75,84,91,39</Scores>
</student>
<student>
<First>Sven</First>
<Last>Mortensen</Last>
<Scores>88,94,65,91</Scores>
</student>
</Root>
Daha fazla bilgi için, bkz. Creating XML Trees in C# (LINQ to XML).
Kaynak Öğeler Üzerinde İşlemler Gerçekleştirme
Çıkış dizisi, kaynak diziden herhangi bir öğe veya öğe özelliği içereyem olabilir. Bunun yerine çıkış, giriş bağımsız değişkenleri olarak kaynak öğeler kullanılarak hesaplanan bir değer dizisi olabilir.
Aşağıdaki sorgu, dairelerin radyanı temsil eden bir sayı dizisi alır, her yarıçap için alanı hesaplar ve hesaplanan alanla biçimlendirilmiş dizeleri içeren bir çıkış dizisi verir.
Çıkış dizisi için her dize, dize ilişkilendirmesi kullanılarak biçimlendirildi. İlişkili bir dize, dizenin açılış tırnak işaretinin önünde bir işaretine sahip olur ve işlemler, irdelenmiş dizenin içine yerleştirilen küme $ ayraçları içinde yapılabilir. Bu işlemler gerçekleştirilecek olan sonuçlar birikecek.
Not
Sorgu başka bir etki alanına çevrilecekse sorgu ifadelerinde çağırma yöntemleri desteklenmiyor. Örneğin, içinde sıradan bir C# yöntemini çağıramaz LINQ - SQL SQL Server için bağlam yoktur. Ancak saklı yordamları yöntemlerle eşler ve çağırabilir. Daha fazla bilgi için bkz. Saklı Yordamlar.
class FormatQuery
{
static void Main()
{
// Data source.
double[] radii = { 1, 2, 3 };
// LINQ query using method syntax.
IEnumerable<string> output =
radii.Select(r => $"Area for a circle with a radius of '{r}' = {r * r * Math.PI:F2}");
/*
// LINQ query using query syntax.
IEnumerable<string> output =
from rad in radii
select $"Area for a circle with a radius of '{rad}' = {rad * rad * Math.PI:F2}";
*/
foreach (string s in output)
{
Console.WriteLine(s);
}
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Area for a circle with a radius of '1' = 3.14
Area for a circle with a radius of '2' = 12.57
Area for a circle with a radius of '3' = 28.27
*/