Dotazy v LINQ to DataSet
Dotaz je výraz, který načítá data ze zdroje dat. Dotazy se obvykle vyjadřují ve specializovaném dotazovacím jazyce, jako je SQL pro relační databáze a XQuery pro XML. Vývojáři se proto museli naučit nový dotazovací jazyk pro každý typ zdroje dat nebo formátu dat, který dotazují. Jazykově integrovaný dotaz (LINQ) nabízí jednodušší konsis režim stanu l pro práci s daty napříč různými druhy zdrojů a formátů dat. V dotazu LINQ vždy pracujete s programovacími objekty.
Operace dotazu LINQ se skládá ze tří akcí: získání zdroje dat nebo zdrojů, vytvoření dotazu a spuštění dotazu.
Zdroje dat, které implementují IEnumerable<T> obecné rozhraní, je možné dotazovat prostřednictvím LINQ. Volání AsEnumerable na vrátí DataTable objekt, který implementuje obecné IEnumerable<T> rozhraní, které slouží jako zdroj dat pro LINQ to DataSet dotazy.
V dotazu zadáte přesně informace, které chcete načíst ze zdroje dat. Dotaz může také určit, jak se mají tyto informace řadit, seskupit a tvarovat před vrácením. V LINQ je dotaz uložen v proměnné. Pokud je dotaz navržený tak, aby vracel posloupnost hodnot, musí být samotná proměnná dotazu výčtovým typem. Tato proměnná dotazu nevyžaduje žádnou akci a nevrací žádná data; ukládá pouze informace o dotazu. Po vytvoření dotazu je nutné tento dotaz spustit, aby se načetla všechna data.
V dotazu, který vrací posloupnost hodnot, proměnná dotazu sama nikdy neuchová výsledky dotazu a ukládá pouze příkazy dotazu. Provádění dotazu je odloženo, dokud se proměnná dotazu nepřečítá v foreach
rámci smyčky nebo For Each
smyčky. Tomu se říká odložené spuštění. To znamená, že provádění dotazu probíhá určitou dobu po vytvoření dotazu. To znamená, že dotaz můžete spustit tak často, jak chcete. To je užitečné například v případě, že máte databázi, která se aktualizuje jinými aplikacemi. V aplikaci můžete vytvořit dotaz, který načte nejnovější informace a opakovaně spustí dotaz a vrátí aktualizované informace pokaždé.
Na rozdíl od odložených dotazů, které vracejí posloupnost hodnot, se dotazy, které vracejí jednu hodnotu, spustí okamžitě. Mezi příklady jednoúčelových dotazů patří Count, Max, Averagea First. Tyto příkazy se spustí okamžitě, protože k výpočtu výsledku singletonu se vyžadují výsledky dotazu. Například aby bylo možné najít průměr výsledků dotazu, musí být dotaz proveden, aby funkce průměrování mohla pracovat se vstupními daty. Pomocí metod nebo ToArray metod dotazu můžete také ToList vynutit okamžité spuštění dotazu, který nevygeneruje jednu hodnotu. Tyto techniky vynucení okamžitého spuštění můžou být užitečné, když chcete ukládat výsledky dotazu do mezipaměti.
Dotazy
Dotazy LINQ to DataSet je možné formulovat ve dvou různých syntaxích: syntaxe výrazů dotazu a syntaxe dotazů založená na metodách.
Syntaxe výrazu dotazu
Výrazy dotazů jsou deklarativní syntaxe dotazu. Tato syntaxe umožňuje vývojáři psát dotazy v jazyce C# nebo Visual Basic ve formátu podobném jazyku SQL. Pomocí syntaxe výrazů dotazu můžete provádět i složité operace filtrování, řazení a seskupování u zdrojů dat s minimálním kódem. Další informace naleznete v tématu LINQ Query Expressions and Basic Query Operations (Visual Basic).
Modul CLR (Common Language Runtime) rozhraní .NET Framework nemůže přečíst samotnou syntaxi výrazu dotazu. Výrazy dotazu se proto v době kompilace překládají na něco, čemu CLR rozumí: volání metody. Tyto metody se označují jako standardní operátory dotazu. Jako vývojář máte možnost je volat přímo pomocí syntaxe metody místo syntaxe dotazu. Další informace naleznete v tématu Syntaxe dotazu a syntaxe metody v LINQ. Další informace o standardních operátorech dotazů naleznete v tématu Přehled operátorů standardních dotazů.
Následující příklad používá Select k vrácení všech řádků z Product
tabulky a zobrazení názvů produktů.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
select product;
Console.WriteLine("Product Names:");
foreach (DataRow p in query)
{
Console.WriteLine(p.Field<string>("Name"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Dim products As DataTable = ds.Tables("Product")
Dim query = From product In products.AsEnumerable() _
Select product
Console.WriteLine("Product Names:")
For Each p In query
Console.WriteLine(p.Field(Of String)("Name"))
Next
Syntaxe dotazů založená na metodách
Druhým způsobem, jak formulovat dotazy LINQ to DataSet, je použití dotazů založených na metodách. Syntaxe dotazu založená na metodě je posloupnost volání přímých metod do metod operátoru LINQ, která předává výrazy lambda jako parametry. Další informace najdete v tématu Výrazy lambda.
Tento příklad používá Select k vrácení všech řádků z Product
a zobrazení názvů produktů.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
var query = products.AsEnumerable().
Select(product => new
{
ProductName = product.Field<string>("Name"),
ProductNumber = product.Field<string>("ProductNumber"),
Price = product.Field<decimal>("ListPrice")
});
Console.WriteLine("Product Info:");
foreach (var productInfo in query)
{
Console.WriteLine("Product name: {0} Product number: {1} List price: ${2} ",
productInfo.ProductName, productInfo.ProductNumber, productInfo.Price);
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Dim products As DataTable = ds.Tables("Product")
Dim query = products.AsEnumerable() _
.Select(Function(product As DataRow) New With _
{ _
.ProductName = product.Field(Of String)("Name"), _
.ProductNumber = product.Field(Of String)("ProductNumber"), _
.Price = product.Field(Of Decimal)("ListPrice") _
})
Console.WriteLine("Product Info:")
For Each product In query
Console.Write("Product name: " & product.ProductName)
Console.Write("Product number: " & product.ProductNumber)
Console.WriteLine("List price: $ " & product.Price)
Next
Vytváření dotazů
Jak jsme zmínili dříve v tomto tématu, proměnná dotazu sama ukládá příkazy dotazu pouze v případě, že je dotaz navržen tak, aby vracel posloupnost hodnot. Pokud dotaz neobsahuje metodu, která způsobí okamžité spuštění, skutečné spuštění dotazu se odloží, dokud nebudete iterovat proměnnou dotazu ve smyčce foreach
nebo For Each
ve smyčce. Odložené spuštění umožňuje sloučení více dotazů nebo rozšíření dotazu. Když se dotaz rozšíří, upraví se tak, aby zahrnoval nové operace a případné spuštění bude odrážet změny. V následujícím příkladu první dotaz vrátí všechny produkty. Druhý dotaz rozšíří první pomocí k Where
vrácení všech produktů velikosti "L":
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> productsQuery =
from product in products.AsEnumerable()
select product;
IEnumerable<DataRow> largeProducts =
productsQuery.Where(p => p.Field<string>("Size") == "L");
Console.WriteLine("Products of size 'L':");
foreach (DataRow product in largeProducts)
{
Console.WriteLine(product.Field<string>("Name"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Dim products As DataTable = ds.Tables("Product")
Dim productsQuery = From product In products.AsEnumerable() _
Select product
Dim largeProducts = _
productsQuery.Where(Function(p) p.Field(Of String)("Size") = "L")
Console.WriteLine("Products of size 'L':")
For Each product In largeProducts
Console.WriteLine(product.Field(Of String)("Name"))
Next
Po provedení dotazu se nedají skládat žádné další dotazy a všechny následné dotazy budou používat operátory LINQ v paměti. Provádění dotazu nastane, když iterujete proměnnou foreach
dotazu v příkazu nebo For Each
v příkazu, nebo voláním některého z operátorů převodu LINQ, které způsobují okamžité spuštění. Mezi tyto operátory patří: ToList, ToArray, ToLookupa ToDictionary.
V následujícím příkladu vrátí první dotaz všechny produkty seřazené podle ceníkové ceny. Metoda ToArray se používá k vynucení okamžitého spuštění dotazu:
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
orderby product.Field<Decimal>("ListPrice") descending
select product;
// Force immediate execution of the query.
IEnumerable<DataRow> productsArray = query.ToArray();
Console.WriteLine("Every price from highest to lowest:");
foreach (DataRow prod in productsArray)
{
Console.WriteLine(prod.Field<Decimal>("ListPrice"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Dim products As DataTable = ds.Tables("Product")
Dim query = _
From product In products.AsEnumerable() _
Order By product.Field(Of Decimal)("ListPrice") Descending _
Select product
' Force immediate execution of the query.
Dim productsArray = query.ToArray()
Console.WriteLine("Every price From highest to lowest:")
For Each prod In productsArray
Console.WriteLine(prod.Field(Of Decimal)("ListPrice"))
Next