Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Standardní operátory dotazu jsou klíčová slova a metody, které tvoří vzor LINQ. Jazyk C# definuje klíčová slova dotazu LINQ, která používáte pro nejběžnější výraz dotazu. Kompilátor překládá výrazy pomocí těchto klíčových slov na ekvivalentní volání metody. Dvě formy jsou synonymem. Jiné metody, které jsou součástí oboru názvů System.Linq, nemají ekvivalentní klíčová slova dotazu. V těchto případech je nutné použít syntaxi metody. Tato část popisuje všechna klíčová slova operátoru dotazu. Modul runtime a další balíčky NuGet přidávají další metody navržené pro práci s dotazy LINQ v jednotlivých verzích. Nejběžnější metody, včetně těch, které mají ekvivalenty klíčových slov dotazu, jsou popsané v této části. Úplný seznam metod dotazů podporovaných modulem runtime .NET najdete v dokumentaci k rozhraní System.Linq.Enumerable API. Kromě zde popsaných metod obsahuje tato třída metody pro zřetězení zdrojů dat, výpočet jedné hodnoty ze zdroje dat, jako je součet, průměr nebo jiná hodnota.
Důležité
Tyto ukázky používají zdroj dat System.Collections.Generic.IEnumerable<T>. Zdroje dat, které jsou založené na System.Linq.IQueryProvider, používají zdroje dat System.Linq.IQueryable<T> a stromy výrazů . Stromy výrazů mají omezení povolené syntaxe jazyka C#. Každý zdroj dat IQueryProvider, například EF Core, může navíc uplatňovat další omezení. Projděte si dokumentaci ke zdroji dat.
Většina z těchto metod působí na sekvencích, kde sekvence je objekt, jehož typ implementuje IEnumerable<T> rozhraní nebo rozhraní IQueryable<T>. Standardní operátory dotazů poskytují možnosti dotazu, včetně filtrování, projekce, agregace, řazení a dalších možností. Metody, které tvoří každou sadu, jsou členy rozšíření definované v jednotlivých EnumerableQueryable třídách. Jsou definovány jako členové rozšíření, kde je typ příjemce buď IEnumerable<T> nebo IQueryable<T> podle toho, na jakém typu pracují.
Rozdíl mezi sekvencemi IEnumerable<T> a IQueryable<T> určuje způsob spuštění dotazu za běhu.
Pro IEnumerable<T>vrácený výčtitelný objekt zachycuje argumenty, které byly předány metodě. Při výčtu tohoto objektu se použije logika operátoru dotazu a vrátí se výsledky dotazu.
Pro IQueryable<T>se dotaz přeloží do stromu výrazů . Strom výrazů lze přeložit na nativní dotaz, když zdroj dat dokáže dotaz optimalizovat. Knihovny, jako je Entity Framework, překládají dotazy LINQ do nativních dotazů SQL, které se spouštějí v databázi.
Následující příklad kódu ukazuje, jak můžete pomocí standardních operátorů dotazu získat informace o sekvenci.
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
Pokud je to možné, dotazy v této části používají jako vstupní zdroj posloupnost slov nebo čísel. Pro dotazy, ve kterých se používají složitější vztahy mezi objekty, se používají následující zdroje, které modelují školu:
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; }
}
Každý Student má stupeň, primární oddělení a řadu skóre.
Teacher má také vlastnost City, která identifikuje areál, ve kterém učitel předměty pořádá. A Department má jméno a referenci na Teacher sloužícího jako vedoucí oddělení.
Sadu dat najdete ve zdrojovém úložišti .
Typy operátorů dotazů
Standardní operátory dotazů se liší v načasování jejich provádění v závislosti na tom, jestli vrací jednu hodnotu nebo posloupnost hodnot. Tyto metody, které vrátí jednu hodnotu (například Average a Sum), se spustí okamžitě. Metody, které vracejí sekvenci odloží provádění dotazu a vrátí výčtový objekt. Výstupní sekvenci jednoho dotazu můžete použít jako vstupní sekvenci do jiného dotazu. Dotazovací metody zřetězujete do jednoho dotazu, což umožňuje, aby dotazy dosáhly libovolné složitosti.
Operátory dotazů
V dotazu LINQ je prvním krokem zadání zdroje dat. V dotazu LINQ přichází klauzule from jako první, aby se zavedl zdroj dat (students) a proměnná rozsahu (student).
//queryAllStudents is an IEnumerable<Student>
var queryAllStudents = from student in students
select student;
Proměnná rozsahu se podobá proměnné iterace ve smyčce foreach s tím rozdílem, že ve výrazu dotazu nedojde k žádné skutečné iteraci. Při spuštění dotazu slouží proměnná rozsahu jako odkaz na každý následný prvek v students. Protože kompilátor může odvodit typ student, nemusíte ho explicitně zadávat. Do klauzule let můžete zavést více proměnných rozsahu. Další informace najdete v tématu let klauzule.
Poznámka:
Pro jiné než obecné zdroje dat, jako například ArrayList, musíte explicitně určit typ proměnné rozsahu. Další informace najdete v tématu Jak dotazovat ArrayList pomocí LINQ (C#) a z klauzule.
Jakmile získáte zdroj dat, můžete na daném zdroji dat provést libovolný počet operací:
-
filtrování dat pomocí klíčového slova
where. -
data objednávek pomocí
orderbya volitelnědescendingklíčových slov. -
Seskupit data pomocí klíčových slov
groupa volitelněinto. -
Připojit data pomocí klíčového slova
join. -
Data projektu pomocí klíčového slova
select.
Tabulka syntaxe výrazů dotazu
Následující tabulka uvádí standardní operátory dotazu, které mají ekvivalentní klauzule výrazu dotazu.
Transformace dat pomocí LINQ
Language-Integrated Dotaz (LINQ) není pouze o načítání dat. Je to také výkonný nástroj pro transformaci dat. Pomocí dotazu LINQ můžete jako vstup použít zdrojovou sekvenci a upravit ji mnoha způsoby, abyste vytvořili novou výstupní sekvenci. Samotnou sekvenci můžete upravit beze změny samotných prvků řazením a seskupením. Ale možná nejvýkonnější funkcí dotazů LINQ je schopnost vytvářet nové typy. Klauzule select vytvoří výstupní prvek ze vstupního elementu. Použijete ho k transformaci vstupního elementu na výstupní element:
- Sloučí více vstupních sekvencí do jedné výstupní sekvence, která má nový typ.
- Vytvořte výstupní sekvence, jejichž prvky se skládají pouze z jedné nebo několika vlastností každého prvku ve zdrojové sekvenci.
- Vytvořte výstupní sekvence, jejichž prvky se skládají z výsledků operací prováděných se zdrojovými daty.
- Vytváření výstupních sekvencí v jiném formátu Můžete například transformovat data z řádků SQL nebo textových souborů do XML.
Tyto transformace můžete kombinovat různými způsoby ve stejném dotazu. Kromě toho můžete jako vstupní sekvenci nového dotazu použít výstupní sekvenci jednoho dotazu. Následující příklad transformuje objekty v datové struktuře v paměti na elementy XML.
// 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);
Kód vytvoří následující výstup XML:
<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>
Další informace najdete v tématu Vytváření stromů XML v jazyce C# (LINQ to XML).
Výsledky jednoho dotazu můžete použít jako zdroj dat pro další dotaz. Tento příklad ukazuje, jak uspořádat výsledky operace spojení. Tento dotaz vytvoří skupinové spojení a pak seřadí skupiny podle department prvku, který je stále v rámci rozsahu. Uvnitř inicializátoru anonymního typu poddotaz seřadí veškeré odpovídající prvky ze sekvence students.
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
*/
Ekvivalentní dotaz pomocí syntaxe metody se zobrazí v následujícím kódu:
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}");
}
}
I když můžete použít orderby klauzuli s jednou nebo více zdrojovými sekvencemi před spojením, obecně ji nedoporučujeme. Někteří zprostředkovatelé LINQ nemusí zachovat toto řazení po spojení. Další informace viz příkaz join.