Sorgu ifadesi temelleri
Bu makalede C# içinde sorgu ifadeleri ile ilgili temel kavramlar tanıtmaktadır.
Sorgu nedir ve ne yapar?
Sorgu, belirli bir veri kaynağından (veya kaynaklardan) hangi verilerin alın gerektiğini ve döndürülen verilerin hangi şekil ve kuruluşa sahip olması gerektiğini açıklayan bir dizi yönergelerdir. Sorgu, ürettiği sonuçlardan farklıdır.
Genellikle, kaynak veriler mantıksal olarak aynı tür öğeler dizisi olarak düzenlenmiştir. Örneğin, veritabanı SQL bir satır dizisi içerir. Xml dosyasında XML öğelerinin bir "dizisi" vardır (bunlar ağaç yapısında hiyerarşik olarak düzenlenmiş olsa da). Bellek içinde bir koleksiyon, bir nesne dizisi içerir.
Uygulamanın bakış açısından özgün kaynak verilerin türü ve yapısı önemli değildir. Uygulama, kaynak verileri her zaman bir veya koleksiyonu IEnumerable<T> olarak IQueryable<T> görür. Örneğin, LINQ to XML, kaynak veriler bir veri kaynağı olarak görünür IEnumerable <XElement>.
Bu kaynak dizisine göre, bir sorgu üç durumdan birini yapar:
Tek tek öğeleri değiştirmeden yeni bir dizi üretmek için öğelerin bir alt kümesini alın. Sorgu daha sonra, aşağıdaki örnekte gösterildiği gibi döndürülen diziyi çeşitli yollarla sıralar veya gruplar (bir
scoresolduğunuint[]varsay):IEnumerable<int> highScoresQuery = from score in scores where score > 80 orderby score descending select score;Önceki örnekte olduğu gibi bir öğe dizisi alın, ancak bunları yeni bir nesne türüne dönüştürin. Örneğin, bir sorgu bir veri kaynağında yer alan belirli müşteri kayıtlarından yalnızca son adları alabilir. Ya da tüm kaydı alabilir ve ardından son sonuç dizisini oluşturmadan önce başka bir bellek içinde nesne türü, hatta XML verileri oluşturmak için kullanabilir. Aşağıdaki örnekte, bir 'den bir'e bir
intprojeksiyonustringgösterir. Yeni türünehighScoresQuerydikkat.IEnumerable<string> highScoresQuery2 = from score in scores where score > 80 orderby score descending select $"The score is {score}";Kaynak veriler hakkında aşağıdaki gibi tek bir değer alın:
Belirli bir koşulla eşan öğelerin sayısı.
En büyük veya en az değere sahip olan öğe.
Bir koşulla eşleşen ilk öğe veya belirtilen öğe kümesinde belirli değerlerin toplamı. Örneğin, aşağıdaki sorgu tamsayı dizisinde 80'den büyük puan
scoressayısını döndürür:int highScoreCount = (from score in scores where score > 80 select score) .Count();Önceki örnekte, yöntemine çağrıdan önce sorgu ifadesinin çevresindeki parantezlerin kullanımına dikkat
Countetmek gerekir. Bunu somut sonucu depolamak için yeni bir değişken kullanarak da ifade edin. Bu teknik daha okunabilir çünkü sorguyu bir sonucu depolar sorgudan ayrı depolar.IEnumerable<int> highScoresQuery3 = from score in scores where score > 80 select score; int scoreCount = highScoresQuery3.Count();
Önceki örnekte, sorgu çağrısında yürütülür çünkü tarafından döndürülen öğe sayısını belirlemek için sonuçlar üzerinde tekrar Count Count olması highScoresQuery gerekir.
Sorgu ifadesi nedir?
Sorgu ifadesi, sorgu söz dizimlerinde ifade ifade eden bir sorgudur. Sorgu ifadesi birinci sınıf bir dil yapısıdır. Aynı diğer tüm ifadelerde olduğu gibi, C# ifadesinin geçerli olduğu herhangi bir bağlamda da kullanılabilir. Sorgu ifadesi, SQL veya XQuery'ye benzer bir bildirimsel söz dizimi ile yazılmış yan tümcelerden oluşur. Her yan tümce sırasıyla bir veya daha fazla C# ifadesi içerir ve bu ifadeler sorgu ifadesi veya sorgu ifadesi içerebilir.
Sorgu ifadesi bir from yan tümcesi ile başlamalı ve bir select veya group yan tümcesi ile bittir. İlk yan tümcesi ile son veya yan tümcesi arasında şu isteğe bağlı yan tümcelerden birini veya daha fazlasını içerebilir: where , orderby , join , let ve hatta from select ek yan group tümceleri. Aynı sorgu ifadesinde ek sorgu yan tümceleri için kaynak olarak hizmet vermek üzere bir or yan tümcesi sonucu etkinleştirmek için into anahtar join group sözcüğünü de kullanabilirsiniz.
Sorgu değişkeni
LINQ'te sorgu değişkeni, sorgunun sonuçları yerine sorguyu depolar. Daha belirgin olarak, sorgu değişkeni her zaman bir deyiminde veya doğrudan yöntemine yapılan bir çağrıda tekrarında bir öğe dizisi üretecek numaralanabilir bir foreach tür IEnumerator.MoveNext olur.
Aşağıdaki kod örneğinde, bir veri kaynağı, bir filtreleme yan tümcesi, bir sıralama yan tümcesi ve kaynak öğelerin dönüşümüne sahip basit bir sorgu ifadesi gösterir. yan select tümcesi sorguyu sonlar.
static void Main()
{
// Data source.
int[] scores = { 90, 71, 82, 93, 75, 82 };
// Query Expression.
IEnumerable<int> scoreQuery = //query variable
from score in scores //required
where score > 80 // optional
orderby score descending // optional
select score; //must end with select or group
// Execute the query to produce the results
foreach (int testScore in scoreQuery)
{
Console.WriteLine(testScore);
}
}
// Outputs: 93 90 82 82
Önceki örnekte, scoreQuery bazen yalnızca sorgu olarak adlandırılan bir sorgu değişkenidir. Sorgu değişkeni, döngüde üretilen gerçek sonuç verilerini foreach depolar. deyimi foreach yürütülürken sorgu sonuçları sorgu değişkeni aracılığıyla scoreQuery döndürülz. Bunun yerine, yineleme değişkeni aracılığıyla testScore döndürülürler. değişkeni scoreQuery ikinci bir döngüde tekrar foreach olabilir. Ne veri kaynağı ne de veri kaynağı değiştirilmeden aynı sonuçları üretir.
Sorgu değişkeni, sorgu söz dizimi veya yöntem söz dizimi ile ifade eden bir sorguyu veya iki birleşimini depolar. Aşağıdaki örneklerde ve değerleri queryMajorCities sorgu queryMajorCities2 değişkenleridir:
//Query syntax
IEnumerable<City> queryMajorCities =
from city in cities
where city.Population > 100000
select city;
// Method-based syntax
IEnumerable<City> queryMajorCities2 = cities.Where(c => c.Population > 100000);
Öte yandan, aşağıdaki iki örnek, her biri bir sorguyla başlatılmış olsa bile sorgu değişkenlerini göstermeyen değişkenleri gösterir. Bunlar sonuçları depolayana kadar sorgu değişkenleri değildir:
int highestScore =
(from score in scores
select score)
.Max();
// or split the expression
IEnumerable<int> scoreQuery =
from score in scores
select score;
int highScore = scoreQuery.Max();
// the following returns the same result
int highScore = scores.Max();
List<City> largeCitiesList =
(from country in countries
from city in country.Cities
where city.Population > 10000
select city)
.ToList();
// or split the expression
IEnumerable<City> largeCitiesQuery =
from country in countries
from city in country.Cities
where city.Population > 10000
select city;
List<City> largeCitiesList2 = largeCitiesQuery.ToList();
Sorguları ifade etmenin farklı yolları hakkında daha fazla bilgi için bkz. LINQ'te sorgu söz dizimi ve yöntem söz dizimi.
Sorgu değişkenlerinin açık ve örtülü yazarak
Bu belge, sorgu değişkeni ile select yan tümcesi arasındaki tür ilişkisini göstermek için genellikle sorgu değişkeninin açık türünü sağlar. Ancak, derleyiciye derleme zamanında bir sorgu değişkeninin türünü (veya başka bir yerel değişkeni) çıkarması talimatı için var anahtar sözcüğünü de kullanabilirsiniz. Örneğin, bu konu başlığında daha önce gösterilen sorgu örneği, örtülü yazarak da ifade edebilirsiniz:
// Use of var is optional here and in all queries.
// queryCities is an IEnumerable<City> just as
// when it is explicitly typed.
var queryCities =
from city in cities
where city.Population > 100000
select city;
Daha fazla bilgi için bkz. LINQ sorgu işlemlerinde örtülü olarak türe sahip yerel değişkenler ve Tür ilişkileri.
Sorgu ifadesi başlatma
Sorgu ifadesinin bir yan tümcesi ile başlaması from gerekir. Bir veri kaynağını bir aralık değişkeniyle birlikte belirtir. Aralık değişkeni, kaynak dizi geçişte olduğu için kaynak dizideki her birbirini takip eden öğeyi temsil eder. Aralık değişkeni, veri kaynağında öğelerin türüne göre kesin olarak türe sahiptir. Aşağıdaki örnekte, bir countries nesne dizisi Country olduğundan, aralık değişkeni olarak da yazıldı. Country Aralık değişkeni kesin olarak yazıldı olduğundan, türün kullanılabilir üyelerine erişmek için nokta işleci kullanabilirsiniz.
IEnumerable<Country> countryAreaQuery =
from country in countries
where country.Area > 500000 //sq km
select country;
Aralık değişkeni, sorgudan noktalı virgülle veya devamlılık yan tümcesi ile çıkılana kadar kapsamdadır.
Sorgu ifadesi birden çok yan tümce from içerebilir. Kaynak from dizideki her öğe bir koleksiyon olduğunda veya bir koleksiyon içerdiğinde ek yan tümceler kullanın. Örneğin, her biri adlı bir nesne Country koleksiyonu içeren bir nesne koleksiyonunuz olduğunu City Cities varsayalım. Her bir içinde City nesneleri sorgulamak Country için burada gösterildiği gibi iki yan from tümcesi kullanın:
IEnumerable<City> cityQuery =
from country in countries
from city in country.Cities
where city.Population > 10000
select city;
Daha fazla bilgi için from yan tümcesine bakın.
Sorgu ifadesini sonlandırma
Sorgu ifadesi yan tümcesi veya yan group tümcesi ile select bitsin.
group tümcesi
Belirttiğiniz group anahtara göre düzenlenmiş bir grup dizisi üretmek için yan tümcesini kullanın. Anahtar herhangi bir veri türü olabilir. Örneğin, aşağıdaki sorgu bir veya daha fazla nesne içeren ve anahtarı değeri ülke adlarının ilk harfi olan bir tür olan Country char bir grup dizisi oluşturur.
var queryCountryGroups =
from country in countries
group country by country.Name[0];
Gruplama hakkında daha fazla bilgi için bkz. group yan tümcesi.
select tümcesi
Diğer select tüm dizi türlerini üretmek için yan tümcesini kullanın. Basit select yan tümcesi yalnızca veri kaynağında bulunan nesnelerle aynı türde nesneler üretir. Bu örnekte, veri kaynağı nesneleri Country içerir. yan orderby tümcesi yalnızca öğeleri yeni bir sırayla sıralar ve yan tümcesi select yeniden sıralandırmış nesnelerin bir dizisini Country üretir.
IEnumerable<Country> sortedQuery =
from country in countries
orderby country.Area
select country;
yan select tümcesi, kaynak verileri yeni tür dizilerine dönüştürmek için kullanılabilir. Bu dönüştürme, projeksiyon olarak da adlandırılmış durumdadır. Aşağıdaki örnekte yan tümcesi, özgün öğedeki alanların yalnızca bir alt kümesini içeren anonim select türlerin bir dizisini projeler. Yeni nesnelerin bir nesne başlatıcı kullanılarak başlatılmış olduğunu unutmayın.
// Here var is required because the query
// produces an anonymous type.
var queryNameAndPop =
from country in countries
select new { Name = country.Name, Pop = country.Population };
Bir yan tümcenin kaynak verileri dönüştürmek için kullanıla tüm yolları select hakkında daha fazla bilgi için bkz. select yan tümcesi.
ile devamlılıkları
Sorguyu depolar into geçici bir tanımlayıcı oluşturmak için or yan select group tümcesinde anahtar sözcüğünü kullanabilirsiniz. Bir gruplama veya seçme işlemi sonrasında bir sorgu üzerinde ek sorgu işlemleri gerçekleştirmeniz gerekirken bunu gerçekleştirin. Aşağıdaki örnekte countries 10 milyonluk aralıklarda popülasyona göre gruplandı. Bu gruplar oluşturulduktan sonra, ek yan tümceler bazı grupları filtreledikten sonra grupları artan düzende sıralar. Bu ek işlemleri gerçekleştirmek için tarafından temsil edilen countryGroup devamlılık gereklidir.
// percentileQuery is an IEnumerable<IGrouping<int, Country>>
var percentileQuery =
from country in countries
let percentile = (int) country.Population / 10_000_000
group country by percentile into countryGroup
where countryGroup.Key >= 20
orderby countryGroup.Key
select countryGroup;
// grouping is an IGrouping<int, Country>
foreach (var grouping in percentileQuery)
{
Console.WriteLine(grouping.Key);
foreach (var country in grouping)
Console.WriteLine(country.Name + ":" + country.Population);
}
Daha fazla bilgi için içine bakın.
Filtreleme, sıralama ve birleştirme
Başlangıç yan tümcesi ile bitiş veya yan tümcesi arasında diğer tüm yan tümceler from ( , , , , select ) group where join orderby from let isteğe bağlıdır. İsteğe bağlı yan tümcelerden herhangi biri, bir sorgu gövdesinde sıfır kez veya birden çok kez kullanılabilir.
where tümcesi
whereBir veya daha fazla koşul ifadesine göre kaynak verilerden öğeleri filtrelemek için yan tümcesini kullanın. whereAşağıdaki örnekteki yan tümce İki koşuldan oluşan bir koşula sahiptir.
IEnumerable<City> queryCityPop =
from city in cities
where city.Population < 200000 && city.Population > 100000
select city;
Daha fazla bilgi için bkz. WHERE yan tümcesi.
orderby tümcesi
orderbySonuçları artan veya azalan sırada sıralamak için yan tümcesini kullanın. Ayrıca, ikincil sıralama düzenleri de belirtebilirsiniz. Aşağıdaki örnek, özelliğini kullanarak nesneler üzerinde birincil bir sıralama gerçekleştirir country Area . Daha sonra özelliğini kullanarak ikincil bir sıralama gerçekleştirir Population .
IEnumerable<Country> querySortedCountries =
from country in countries
orderby country.Area, country.Population descending
select country;
ascendingAnahtar sözcüğü isteğe bağlıdır; herhangi bir sipariş belirtilmemişse varsayılan sıralama düzeni olur. Daha fazla bilgi için bkz. OrderBy tümcesi.
join tümcesi
Bir join veri kaynağındaki öğeleri, her bir öğesinde belirtilen anahtarlar arasındaki eşitlik karşılaştırmasını temel alarak başka bir veri kaynağındaki öğelerle ilişkilendirmek ve/veya birleştirmek için yan tümcesini kullanın. LINQ ' ta, öğeleri farklı türlerde olan nesne dizileri üzerinde JOIN işlemleri gerçekleştirilir. İki dizinin birleştirildikten sonra, select group Çıkış dizisinde hangi öğenin depolanacağını belirtmek için bir veya ifadesini kullanmanız gerekir. Ayrıca, her bir ilişkili öğe kümesinden özellikleri, çıkış sırası için yeni bir türe birleştirmek üzere anonim bir tür de kullanabilirsiniz. Aşağıdaki örnek, prod Category özelliği dize dizisindeki kategorilerden biriyle eşleşen nesneleri ilişkilendirir categories . Categoryİçindeki herhangi bir dizeyle eşleşmeyen ürünler categories filtrelenmez. selectİfade, özellikleri ve öğelerinin her ikisi de alınmış yeni bir tür cat prod .
var categoryQuery =
from cat in categories
join prod in products on cat equals prod.Category
select new { Category = cat, Name = prod.Name };
Ayrıca, ın join anahtar sözcüğünü kullanarak işlemin sonuçlarını geçici bir değişkene depolayarak bir grup birleşimi gerçekleştirebilirsiniz. Daha fazla bilgi için bkz. JOIN yan tümcesi.
let tümcesi
letYöntem çağrısı gibi bir ifadenin sonucunu yeni bir Aralık değişkeninde depolamak için yan tümcesini kullanın. Aşağıdaki örnekte, Range değişkeni firstName tarafından döndürülen dizelerin dizisinin ilk öğesini depolar Split .
string[] names = { "Svetlana Omelchenko", "Claire O'Donnell", "Sven Mortensen", "Cesar Garcia" };
IEnumerable<string> queryFirstNames =
from name in names
let firstName = name.Split(' ')[0]
select firstName;
foreach (string s in queryFirstNames)
Console.Write(s + " ");
//Output: Svetlana Claire Sven Cesar
Daha fazla bilgi için bkz. Let yan tümcesi.
Sorgu ifadesinde alt sorgular
Sorgu yan tümcesi, bazen alt sorgu olarak adlandırılan bir sorgu ifadesi içerebilir. Her bir alt sorgu from , ilk yan tümcesindeki aynı veri kaynağını işaret etmek zorunda olmayan kendi yan tümcesiyle başlar from . Örneğin, aşağıdaki sorgu, Gruplandırma işleminin sonuçlarını almak için SELECT deyiminde kullanılan bir sorgu ifadesini gösterir.
var queryGroupMax =
from student in students
group student by student.GradeLevel into studentGroup
select new
{
Level = studentGroup.Key,
HighestScore =
(from student2 in studentGroup
select student2.Scores.Average())
.Max()
};
Daha fazla bilgi için bkz. Gruplandırma işleminde alt sorgu gerçekleştirme.