Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Sorgu, veri kaynağından veri alan bir ifadedir. Farklı veri kaynakları, ilişkisel veritabanları için SQL ve XML için XQuery gibi farklı yerel sorgu dillerine sahiptir. Geliştiricilerin desteklemesi gereken her veri kaynağı veya veri biçimi türü için yeni bir sorgu dili öğrenmesi gerekir. LINQ, veri kaynağı ve biçim türleri için tutarlı bir C# dil modeli sunarak bu durumu basitleştirir. LINQ sorgusunda her zaman C# nesneleriyle çalışırsınız. BIR LINQ sağlayıcısı kullanılabilir olduğunda XML belgelerindeki, SQL veritabanlarındaki, .NET koleksiyonlarındaki ve diğer biçimlerdeki verileri sorgulamak ve dönüştürmek için aynı temel kodlama desenlerini kullanırsınız.
Sorgu İşleminin Üç Bölümü
Tüm LINQ sorgu işlemleri üç ayrı eylemden oluşur:
- Veri kaynağını alın.
- Sorguyu oluşturun.
- Sorguyu çalıştır.
Aşağıdaki örnekte, bir sorgu işleminin üç bölümünün kaynak kodunda nasıl ifade edildiği gösterilmektedir. Örnekte kolaylık sağlamak için veri kaynağı olarak bir tamsayı dizisi kullanılır; ancak, aynı kavramlar diğer veri kaynakları için de geçerlidir. Bu örnek, bu makalenin geri kalanında başvuruda bulunulacaktır.
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = [ 0, 1, 2, 3, 4, 5, 6 ];
// 2. Query creation.
// numQuery is an IEnumerable<int>
var numQuery = from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
Aşağıdaki çizimde sorgu işleminin tamamı gösterilmektedir. LINQ'de, sorgunun yürütülmesi sorgunun kendisinden farklıdır. Başka bir deyişle, sorgu değişkeni oluşturarak herhangi bir veri almazsınız.
Veri Kaynağı
Yukarıdaki örnekteki veri kaynağı, genel IEnumerable<T> arabirimi destekleyen bir dizidir. Bu gerçek, LINQ ile sorgulanabileceği anlamına gelir. Sorgu bir foreach
deyiminde yürütülür ve foreach
gerektirir IEnumerable veya IEnumerable<T>. Destekleyen IEnumerable<T> türler veya genel IQueryable<T> gibi türetilmiş arabirimler sorgulanabilir türler olarak adlandırılır.
Sorgulanabilir bir tür, LINQ veri kaynağı olarak hizmet vermek için değişiklik veya özel işlem gerektirmez. Kaynak veriler sorgulanabilir bir tür olarak bellekte değilse, LINQ sağlayıcısı bunu bu şekilde temsil etmelidir. Örneğin, LINQ to XML bir XML belgesini sorgulanabilir XElement bir türe yükler:
// Create a data source from an XML document.
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");
EntityFramework ile C# sınıfları ile veritabanı şemanız arasında nesne ilişkisel eşleme oluşturursunuz. Sorgularınızı nesnelere yazarsınız ve çalışma zamanında EntityFramework veritabanıyla iletişimi işler. Aşağıdaki örnekte veritabanındaki Customers
belirli bir tabloyu temsil eder ve sorgu sonucunun türü , IQueryable<T>türünden IEnumerable<T>türetilir.
Northwnd db = new Northwnd(@"c:\northwnd.mdf");
// Query for customers in London.
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
Belirli veri kaynağı türlerini oluşturma hakkında daha fazla bilgi için çeşitli LINQ sağlayıcılarının belgelerine bakın. Ancak temel kural basittir: LINQ veri kaynağı, genel IEnumerable<T> arabirimi destekleyen herhangi bir nesne veya genellikle ondan IQueryable<T>devralan bir arabirimdir.
Uyarı
Genel olmayan ArrayList arabirimini destekleyen IEnumerable gibi türler, aynı şekilde bir LINQ veri kaynağı olarak da kullanılabilir. Daha fazla bilgi için bkz. LINQ (C#) ile ArrayList sorgulama.
Sorgu
Sorgu, veri kaynağından veya kaynaklardan alınacak bilgileri belirtir. İsteğe bağlı olarak, sorgu bu bilgilerin döndürülmeden önce nasıl sıralanacağını, gruplandırılmasını ve şekillendirilmesi gerektiğini de belirtir. Sorgu bir sorgu değişkeninde depolanır ve sorgu ifadesiyle başlatılır. Sorgu yazmak için C# sorgu söz dizimlerini kullanırsınız.
Önceki örnekteki sorgu, tamsayı dizisindeki tüm çift sayıları döndürür. Sorgu ifadesi üç yan tümce içerir: from
, where
ve select
. (SQL hakkında bilginiz varsa, yan tümcelerinin sırasının SQL'deki sıraylan ters çevrildiğini fark ettiniz.) from
yan tümcesi veri kaynağını, where
yan tümcesi filtreyi uygular ve select
yan tümcesi döndürülen öğelerin türünü belirtir. Tüm sorgu yan tümceleri bu bölümde ayrıntılı olarak açıklanmıştır. Şimdilik önemli nokta, LINQ'te sorgu değişkeninin kendi başına hiçbir işlem gerçekleştirmemesi ve veri döndürmemesidir. Yalnızca sorgu daha sonraki bir noktada yürütülürken sonuçları üretmek için gereken bilgileri depolar. Sorguların nasıl oluşturulur hakkında daha fazla bilgi için bkz. Standart Sorgu İşleçlerine Genel Bakış (C#).
Uyarı
Sorgular, yöntem söz dizimi kullanılarak da ifade edilebilir. Daha fazla bilgi için bkz. LINQ'te Sorgu Söz Dizimi ve Yöntem Söz Dizimi.
Standart sorgu işleçlerinin yürütme şekline göre sınıflandırılması
Standart sorgu işleci yöntemlerinin LINQ to Objects uygulamaları iki ana yoldan biriyle yürütülür: anında veya ertelenmiş. Ertelenmiş yürütme kullanan sorgu işleçleri ek olarak iki kategoriye ayrılabilir: akış ve akışsız.
Hemen
Anında yürütme, veri kaynağının okunduğu ve işlemin bir kez gerçekleştirildiği anlamına gelir. Skaler sonuç döndüren tüm standart sorgu işleçleri hemen yürütülür. Bu tür sorgulara örnek olarak Count
, Max
, Average
ve First
verilebilir. Bu yöntemler, sorgunun bir sonuç döndürmek için foreach
kullanması gerektiğinden, açık bir foreach
deyim olmadan yürütülür. Bu sorgular koleksiyon değil tek bir IEnumerable
değer döndürür. veya yöntemlerini kullanarak Enumerable.ToList sorguyu Enumerable.ToArray hemen yürütülmeye zorlayabilirsiniz. Anında yürütme, sorgu bildirimini değil sorgu sonuçlarının yeniden kullanılmasını sağlar. Sonuçlar bir kez alınır ve daha sonra kullanılmak üzere depolanır. Aşağıdaki sorgu, kaynak dizideki çift sayıların sayısını döndürür:
var evenNumQuery = from num in numbers
where (num % 2) == 0
select num;
int evenNumCount = evenNumQuery.Count();
Herhangi bir sorgunun hemen yürütülmesini zorlamak ve sonuçlarını önbelleğe almak için ToList veya ToArray yöntemlerini çağırabilirsiniz.
List<int> numQuery2 = (from num in numbers
where (num % 2) == 0
select num).ToList();
// or like this:
// numQuery3 is still an int[]
var numQuery3 = (from num in numbers
where (num % 2) == 0
select num).ToArray();
Ayrıca sorgu ifadesinin foreach
hemen arkasına döngü koyarak yürütmeyi zorlayabilirsiniz. Ancak, çağırarak ToList
veya ToArray
tüm verileri tek bir koleksiyon nesnesinde önbelleğe alırsınız.
Ertelenmiş
Ertelenmiş yürütme, işlemin sorgunun bildirildiği kod noktasında gerçekleştirilmiyor olduğu anlamına gelir. İşlem yalnızca sorgu değişkeni numaralandırıldığında, örneğin bir foreach
deyimi kullanılarak gerçekleştirilir. Sorguyu yürütmenin sonuçları, sorgu tanımlandığında değil, sorgu yürütülürken veri kaynağının içeriğine bağlıdır. Sorgu değişkeni birden çok kez numaralandırılırsa, sonuçlar her seferinde farklı olabilir. Dönüş türü IEnumerable<T> veya IOrderedEnumerable<TElement> olan neredeyse tüm standart sorgu operatörleri, ertelenmiş bir şekilde yürütülür. Ertelenmiş yürütme, sorgu sonuçları her yinelendiğinde sorgu güncelleştirilmiş verileri veri kaynağından aldığından sorgunun yeniden kullanılmasını sağlar. Aşağıdaki kod, ertelenmiş yürütme örneğini gösterir:
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
Deyimi foreach
, sorgu sonuçlarının da alındığı yerdir. Örneğin, önceki sorguda yineleme değişkeni num
döndürülen dizideki her değeri (birer birer) tutar.
Sorgu değişkeninin kendisi sorgu sonuçlarını hiçbir zaman tutmadığından, güncelleştirilmiş verileri almak için bunu tekrar tekrar yürütebilirsiniz. Örneğin, ayrı bir uygulama veritabanını sürekli güncelleştirebilir. Uygulamanızda, en son verileri alan bir sorgu oluşturabilir ve güncelleştirilmiş sonuçları almak için bu sorguyu aralıklarla yürütebilirsiniz.
Ertelenmiş yürütme kullanan sorgu işleçleri ek olarak akış veya akışsız olarak sınıflandırılabilir.
Yayın
Akış işleçlerinin öğeleri sağlamadan önce tüm kaynak verileri okuması gerekmez. Yürütme sırasında, bir akış operatörü her kaynak eleman üzerinde okundukça işlemini gerçekleştirir ve uygunsa öğeyi üretir. Akış işleci, sonuç öğesi üretilene kadar kaynak öğeleri okumaya devam eder. Bu, bir sonuç öğesi üretmek için birden fazla kaynak öğenin okunabileceği anlamına gelir.
Yayınlanmayan
Akışsız işleçlerin bir sonuç öğesi elde etmeden önce tüm kaynak verileri okuması gerekir. Sıralama veya gruplandırma gibi işlemler bu kategoriye girer. Yürütme sırasında, akışsız sorgu işleçleri tüm kaynak verileri okur, bir veri yapısına ekler, işlemi gerçekleştirir ve sonuçta elde edilen öğeleri verir.
Sınıflandırma tablosu
Aşağıdaki tablo, her standart sorgu işleci yöntemini yürütme yöntemine göre sınıflandırır.
Uyarı
bir işleç iki sütunda işaretlenmişse, işleme iki giriş dizisi dahil edilir ve her dizi farklı değerlendirilir. Bu gibi durumlarda, her zaman parametre listesindeki ertelenmiş, akış biçiminde değerlendirilen ilk sıradır.
LINQ to Objects
"LINQ to Objects", doğrudan herhangi bir IEnumerable veya IEnumerable<T> koleksiyon ile LINQ sorgularının kullanımını ifade eder. LINQ kullanarak , List<T>veya Arraygibi Dictionary<TKey,TValue>numaralandırılabilir koleksiyonları sorgulayabilirsiniz. Koleksiyon kullanıcı tanımlı veya .NET API tarafından döndürülen bir tür olabilir. LINQ yaklaşımında, ne almak istediğinizi açıklayan bildirim temelli kod yazarsınız. LINQ to Objects, LINQ ile programlamaya harika bir giriş sağlar.
LINQ sorguları, geleneksel foreach
döngülere göre üç temel avantaj sunar:
- Özellikle birden çok koşul filtrelendiğinde daha kısa ve okunabilirdir.
- En az uygulama koduyla güçlü filtreleme, sıralama ve gruplandırma özellikleri sağlar.
- Bunlar çok az değişiklikle veya hiç değişiklik yapılmadan diğer veri kaynaklarına taşınabilir.
Veriler üzerinde gerçekleştirmek istediğiniz işlem ne kadar karmaşık olursa, geleneksel yineleme teknikleri yerine LINQ kullanarak o kadar avantajlı olursunuz.
Sorgunun sonuçlarını bellekte depolama
Sorgu temelde verileri alma ve düzenleme yönergeleri kümesidir. Sonuçtaki sonraki her öğe istendiği için sorgular gevşek olarak yürütülür. Sonuçları yinelemek için kullandığınızda foreach
, öğelere erişildikçe döndürülür. Bir sorguyu değerlendirmek ve döngü yürütmeden foreach
sonuçlarını depolamak için sorgu değişkeninde aşağıdaki yöntemlerden birini çağırmak gerekir:
Aşağıdaki örnekte gösterildiği gibi sorgu sonuçlarını depolarken döndürülen koleksiyon nesnesini yeni bir değişkene atamanız gerekir:
List<int> numbers = [ 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ];
IEnumerable<int> queryFactorsOfFour = from num in numbers
where num % 4 == 0
select num;
// Store the results in a new variable
// without executing a foreach loop.
var factorsofFourList = queryFactorsOfFour.ToList();
// Read and write from the newly created list to demonstrate that it holds data.
Console.WriteLine(factorsofFourList[2]);
factorsofFourList[2] = 0;
Console.WriteLine(factorsofFourList[2]);