Sdílet prostřednictvím


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

Viz také