Aracılığıyla paylaş


Standart sorgu işleçlerine genel bakış

Standart sorgu işleçleri, LINQ desenini oluşturan anahtar sözcükler ve yöntemlerdir. C# dili, en yaygın sorgu ifadesi için kullandığınız LINQ sorgu anahtar sözcüklerini tanımlar. Derleyici, bu anahtar sözcükleri kullanarak ifadeleri eşdeğer yöntem çağrılarına çevirir. İki form eş anlamlıdır. Ad alanının parçası olan diğer yöntemlerin System.Linq eşdeğer sorgu anahtar sözcükleri bulunmamaktadır. Bu gibi durumlarda yöntem söz dizimini kullanmanız gerekir. Bu bölüm tüm sorgu işleci anahtar sözcüklerini kapsar. Çalışma zamanı ve diğer NuGet paketleri, her sürümde LINQ sorguları ile çalışmak üzere tasarlanmış daha fazla yöntem ekler. Sorgu anahtar sözcüğü eşdeğerlerine sahip olanlar da dahil olmak üzere en yaygın yöntemler bu bölümde ele alınmıştır. .NET Çalışma Zamanı tarafından desteklenen sorgu yöntemlerinin tam listesi için API belgelerine System.Linq.Enumerable bakın. Burada ele alınan yöntemlere ek olarak, bu sınıf veri kaynaklarını birleştirmeye, bir veri kaynağından toplam, ortalama veya başka bir değer gibi tek bir değeri hesaplamaya yönelik yöntemler içerir.

Önemli

Bu örnekler bir System.Collections.Generic.IEnumerable<T> veri kaynağı kullanır. System.Linq.IQueryProvider tabanlı veri kaynakları, System.Linq.IQueryable<T> veri kaynakları ve ifade ağaçları kullanır. İfade ağaçlarının izin verilen C# söz diziminde sınırlamaları vardır. Ayrıca IQueryProvider gibi her veri kaynağı daha fazla kısıtlama uygulayabilir. Veri kaynağınızın belgelerine bakın.

Bu yöntemlerin çoğu diziler üzerinde çalışır; burada bir dizi, türü IEnumerable<T> arabirimini veya IQueryable<T> arabirimini uygulayan bir nesnedir. Standart sorgu işleçleri filtreleme, yansıtma, toplama, sıralama ve daha fazlası gibi sorgu özellikleri sağlar. Her kümeyi oluşturan yöntemler sırasıyla Enumerable ve Queryable sınıflarında tanımlanan uzantı üyeleridir. Onlar, alıcı türünün üzerinde çalıştıkları ya ya da türü olduğu uzantı üyeleri olarak tanımlanır.

ve IEnumerable<T> dizileri arasındaki IQueryable<T> fark, sorgunun çalışma zamanında nasıl yürütüleceğini belirler.

IEnumerable<T> için, döndürülen numaralandırılabilir nesne yönteme geçirilen bağımsız değişkenleri yakalar. Bu nesne numaralandırıldığında, sorgu işlecinin mantığı kullanılır ve sorgu sonuçları döndürülür.

için IQueryable<T>sorgu bir ifade ağacına çevrilir. Veri kaynağı sorguyu iyileştirebildiğinde ifade ağacı yerel sorguya çevrilebilir. Entity Framework gibi kitaplıklar LINQ sorgularını veritabanında yürütülen yerel SQL sorgularına çevirir.

Aşağıdaki kod örneği, bir dizi hakkında bilgi almak için standart sorgu işleçlerini nasıl kullanabileceğinizi gösterir.

string sentence = "the quick brown fox jumps over the lazy dog";
// Split the string into individual words to create a collection.
string[] words = sentence.Split(' ');

// Using query expression syntax.
var query = from word in words
            group word.ToUpper() by word.Length into gr
            orderby gr.Key
            select new { Length = gr.Key, Words = gr };

// Using method-based query syntax.
var query2 = words.
    GroupBy(w => w.Length, w => w.ToUpper()).
    Select(g => new { Length = g.Key, Words = g }).
    OrderBy(o => o.Length);

foreach (var obj in query)
{
    Console.WriteLine($"Words of length {obj.Length}:");
    foreach (string word in obj.Words)
        Console.WriteLine(word);
}

// This code example produces the following output:
//
// Words of length 3:
// THE
// FOX
// THE
// DOG
// Words of length 4:
// OVER
// LAZY
// Words of length 5:
// QUICK
// BROWN
// JUMPS

Mümkün olduğunda, bu bölümdeki sorgular giriş kaynağı olarak bir sözcük veya sayı dizisi kullanır. Nesneler arasındaki daha karmaşık ilişkilerin kullanıldığı sorgular için, bir okulu modelleyen aşağıdaki kaynaklar kullanılır:

public enum GradeLevel
{
    FirstYear = 1,
    SecondYear,
    ThirdYear,
    FourthYear
};

public class Student
{
    public required string FirstName { get; init; }
    public required string LastName { get; init; }
    public required int ID { get; init; }

    public required GradeLevel Year { get; init; }
    public required List<int> Scores { get; init; }

    public required int DepartmentID { get; init; }
}

public class Teacher
{
    public required string First { get; init; }
    public required string Last { get; init; }
    public required int ID { get; init; }
    public required string City { get; init; }
}

public class Department
{
    public required string Name { get; init; }
    public int ID { get; init; }

    public required int TeacherID { get; init; }
}

Her Student birinin bir not düzeyi, bir birincil bölüm ve bir dizi puanı vardır. Ayrıca, Teacher öğretmenin ders aldığı kampüsü tanımlayan bir City özelliği de vardır. Bir Department'nin bir adı ve bölüm başkanı olarak görev yapan bir Teacher'ye bir referansı vardır.

Veri kümesini kaynak depoda bulabilirsiniz.

Sorgu işleç türleri

Standart sorgu işleçleri, tek bir değer mi yoksa bir değer dizisi mi döndürdiklerine bağlı olarak yürütme zamanlamalarında farklılık gösterir. Tek değer döndüren yöntemler (Average ve Sum gibi) hemen yürütülür. Sıra döndüren yöntemler sorgu yürütmesini erteler ve numaralandırılabilir bir nesne döndürür. Bir sorgunun çıkış sırasını, başka bir sorguya giriş dizisi olarak kullanabilirsiniz. Sorgu yöntemlerini tek bir sorguda birbirine zincirlersiniz ve bu da sorguların rastgele karmaşık hale gelmesini sağlar.

Sorgu işleçleri

LINQ sorgusunda ilk adım veri kaynağını belirtmektir. LINQ sorgusunda from yan tümcesi, veri kaynağını () ve students (student) tanıtmak için önce gelir.

//queryAllStudents is an IEnumerable<Student>
var queryAllStudents = from student in students
                        select student;

Aralık değişkeni, bir foreach sorgu ifadesinde gerçek yineleme olmaması dışında döngüdeki yineleme değişkenine benzer. Sorgu yürütülürken, aralık değişkeni içindeki studentsardışık her öğeye bir başvuru görevi görür. Derleyici student türünü çıkarabildiğinden, açıkça belirtmeniz gerekmez. Yan let tümcesinde daha fazla aralık değişkeni ekleyebilirsiniz. Daha fazla bilgi için bkz. let ifadesi.

Uyarı

gibi ArrayListgenel olmayan veri kaynakları için aralık değişkenini açıkça yazmanız gerekir. Daha fazla bilgi için bkz. LINQ (C#) ile ArrayList sorgulama ve from yan tümcesi.

Bir veri kaynağı edindikten sonra, bu veri kaynağı üzerinde istediğiniz sayıda işlem gerçekleştirebilirsiniz:

Sorgu ifadesi söz dizimi tablosu

Aşağıdaki tabloda eşdeğer sorgu ifadesi yan tümcelerine sahip standart sorgu işleçleri listelenmiştir.

Yöntem C# sorgu ifadesi söz dizimi
Cast Açıkça yazılan bir aralık değişkeni kullanın:

from int i in numbers

(Daha fazla bilgi için bkz from yan tümcesi.)
GroupBy group … by …

-veya-

group … by … into …

(Daha fazla bilgi için bkz. grup cümlesi.)
GroupJoin<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,IEnumerable<TInner>, TResult>) join … in … on … equals … into …

(Daha fazla bilgi için bkz. join yan tümcesi.)
Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,TInner,TResult>) join … in … on … equals …

(Daha fazla bilgi için bkz. join yan tümcesi.)
OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>) orderby

(Daha fazla bilgi için bkz . orderby yan tümcesi.)
OrderByDescending<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>) orderby … descending

(Daha fazla bilgi için bkz . orderby yan tümcesi.)
Select select

(Daha fazla bilgi için bkz. select yan tümcesi.)
SelectMany Birden çok from yan tümce.

(Daha fazla bilgi için bkz from yan tümcesi.)
ThenBy<TSource,TKey>(IOrderedEnumerable<TSource>, Func<TSource,TKey>) orderby …, …

(Daha fazla bilgi için bkz . orderby yan tümcesi.)
ThenByDescending<TSource,TKey>(IOrderedEnumerable<TSource>, Func<TSource,TKey>) orderby …, … descending

(Daha fazla bilgi için bkz . orderby yan tümcesi.)
Where where

(Daha fazla bilgi için where yan tümcesine bakın.)

LINQ ile veri dönüştürmeleri

Language-Integrated Sorgusu (LINQ) yalnızca verileri almakla ilgili değildir. Ayrıca verileri dönüştürmeye yönelik güçlü bir araçtır. LINQ sorgusu kullanarak, giriş olarak bir kaynak diziyi kullanabilir ve yeni bir çıkış dizisi oluşturmak için birçok yolla değiştirebilirsiniz. Sıralama ve gruplandırma yoluyla öğeleri 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şturabilmektir. select yan tümcesi bir giriş öğesinden bir çıkış öğesi oluşturur. Bunu bir giriş öğesini çıkış öğesine dönüştürmek için kullanırsınız:

  • Birden çok giriş dizisini yeni bir türe sahip tek bir çıkış dizisiyle birleştirin.
  • Öğeleri kaynak dizideki her öğenin yalnızca bir veya birkaç özelliğinden oluşan çı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 SQL satırlarından veya metin dosyalarından XML'ye dönüştürebilirsiniz.

Bu dönüştürmeleri aynı sorguda çeşitli şekillerde birleştirirsiniz. Ayrıca, bir sorgunun çıkış sırasını yeni bir sorgunun giriş dizisi olarak kullanabilirsiniz. Aşağıdaki örnek, bellek içi veri yapısındaki nesneleri XML öğelerine dönüştürür.


// 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.FirstName),
                new XElement("Last", student.LastName),
                new XElement("Scores", scores)
            ) // end "student"
        ); // end "Root"

// Execute the query.
Console.WriteLine(studentsToXML);

Kod aşağıdaki XML çıkışını oluşturur:

<Root>
  <student>
    <First>Svetlana</First>
    <Last>Omelchenko</Last>
    <Scores>97,90,73,54</Scores>
  </student>
  <student>
    <First>Claire</First>
    <Last>O'Donnell</Last>
    <Scores>56,78,95,95</Scores>
  </student>
  ...
  <student>
    <First>Max</First>
    <Last>Lindgren</Last>
    <Scores>86,88,96,63</Scores>
  </student>
  <student>
    <First>Arina</First>
    <Last>Ivanova</Last>
    <Scores>93,63,70,80</Scores>
  </student>
</Root>

Daha fazla bilgi için bkz. C# dilinde XML Ağaçları Oluşturma (LINQ to XML).

Sonraki sorgu için veri kaynağı olarak bir sorgunun sonuçlarını kullanabilirsiniz. Bu örnekte birleştirme işleminin sonuçlarının nasıl sıralanması gösterilmektedir. Bu sorgu, bir grup birleştirme oluşturur ve ardından hala kapsamda olan department öğesine göre grupları sıralar. Anonim tür başlatıcısının içinde bir alt sorgu, students dizisindeki tüm eşleşen öğeleri sıralar.

var orderedQuery = from department in departments
                   join student in students on department.ID equals student.DepartmentID into studentGroup
                   orderby department.Name
                   select new
                   {
                       DepartmentName = department.Name,
                       Students = from student in studentGroup
                                  orderby student.LastName
                                    select student
                   };

foreach (var departmentList in orderedQuery)
{
    Console.WriteLine(departmentList.DepartmentName);
    foreach (var student in departmentList.Students)
    {
        Console.WriteLine($"  {student.LastName,-10} {student.FirstName,-10}");
    }
}
/* Output:
Chemistry
  Balzan     Josephine
  Fakhouri   Fadi
  Popov      Innocenty
  Seleznyova Sofiya
  Vella      Carmen
Economics
  Adams      Terry
  Adaobi     Izuchukwu
  Berggren   Jeanette
  Garcia     Cesar
  Ifeoma     Nwanneka
  Jamuike    Ifeanacho
  Larsson    Naima
  Svensson   Noel
  Ugomma     Ifunanya
Engineering
  Axelsson   Erik
  Berg       Veronika
  Engström   Nancy
  Hicks      Cassie
  Keever     Bruce
  Micallef   Nicholas
  Mortensen  Sven
  Nilsson    Erna
  Tucker     Michael
  Yermolayeva Anna
English
  Andersson  Sarah
  Feng       Hanying
  Ivanova    Arina
  Jakobsson  Jesper
  Jensen     Christiane
  Johansson  Mark
  Kolpakova  Nadezhda
  Omelchenko Svetlana
  Urquhart   Donald
Mathematics
  Frost      Gaby
  Garcia     Hugo
  Hedlund    Anna
  Kovaleva   Katerina
  Lindgren   Max
  Maslova    Evgeniya
  Olsson     Ruth
  Sammut     Maria
  Sazonova   Anastasiya
Physics
  Åkesson    Sami
  Edwards    Amy E.
  Falzon     John
  Garcia     Debra
  Hansson    Sanna
  Mattsson   Martina
  Richardson Don
  Zabokritski Eugene
*/

Yöntem söz dizimini kullanan eşdeğer sorgu aşağıdaki kodda gösterilir:

var orderedQuery = departments
    .GroupJoin(students, department => department.ID, student => student.DepartmentID,
    (department, studentGroup) => new
    {
        DepartmentName = department.Name,
        Students = studentGroup.OrderBy(student => student.LastName)
    })
    .OrderBy(department => department.DepartmentName);


foreach (var departmentList in orderedQuery)
{
    Console.WriteLine(departmentList.DepartmentName);
    foreach (var student in departmentList.Students)
    {
        Console.WriteLine($"  {student.LastName,-10} {student.FirstName,-10}");
    }
}

Birleştirmeden önce bir veya daha fazla kaynak dizisi ile orderby tümcesi kullanabilirsiniz ancak bunu genellikle önermeyiz. Bazı LINQ sağlayıcıları, birleştirmeden sonra bu sıralamayı koruyamayabilir. Daha fazla bilgi için bkz. join yan tümcesi.

Ayrıca bkz.