Dela via


Frågor i LINQ till DataSet

En fråga är ett uttryck som hämtar data från en datakälla. Frågor uttrycks vanligtvis i ett specialiserat frågespråk, till exempel SQL för relationsdatabaser och XQuery för XML. Därför har utvecklare varit tvungna att lära sig ett nytt frågespråk för varje typ av datakälla eller dataformat som de frågar efter. Språkintegrerad fråga (LINQ) erbjuder en enklare consis tältläge l för att arbeta med data över olika typer av datakällor och format. I en LINQ-fråga arbetar du alltid med programmeringsobjekt.

En LINQ-frågeåtgärd består av tre åtgärder: hämta datakällan eller källorna, skapa frågan och kör frågan.

Datakällor som implementerar det IEnumerable<T> allmänna gränssnittet kan efterfrågas via LINQ. Anropar AsEnumerable ett DataTable returnerar ett objekt som implementerar det allmänna IEnumerable<T> gränssnittet, som fungerar som datakälla för LINQ till DataSet-frågor.

I frågan anger du exakt den information som du vill hämta från datakällan. En fråga kan också ange hur den informationen ska sorteras, grupperas och formas innan den returneras. I LINQ lagras en fråga i en variabel. Om frågan är utformad för att returnera en sekvens med värden måste själva frågevariabeln vara en uppräkningsbar typ. Den här frågevariabeln vidtar ingen åtgärd och returnerar inga data. den lagrar bara frågeinformationen. När du har skapat en fråga måste du köra frågan för att hämta data.

I en fråga som returnerar en sekvens med värden innehåller själva frågevariabeln aldrig frågeresultatet och lagrar bara frågekommandona. Körningen av frågan skjuts upp tills frågevariabeln itereras över i en foreach eller For Each -loop. Det här kallas för uppskjuten körning, dvs. frågekörning inträffar en tid efter att frågan har konstruerats. Det innebär att du kan köra en fråga så ofta du vill. Detta är användbart när du till exempel har en databas som uppdateras av andra program. I ditt program kan du skapa en fråga för att hämta den senaste informationen och köra frågan upprepade gånger och returnera den uppdaterade informationen varje gång.

Till skillnad från uppskjutna frågor, som returnerar en sekvens med värden, körs frågor som returnerar ett singleton-värde omedelbart. Några exempel på singleton-frågor är Count, Max, Averageoch First. Dessa körs omedelbart eftersom frågeresultatet krävs för att beräkna singleton-resultatet. För att till exempel hitta medelvärdet av frågeresultatet måste frågan köras så att genomsnittsfunktionen har indata att arbeta med. Du kan också använda ToList metoderna eller ToArray på en fråga för att framtvinga omedelbar körning av en fråga som inte genererar ett singleton-värde. Dessa tekniker för att tvinga fram omedelbar körning kan vara användbara när du vill cachelagra resultatet av en fråga.

Frågor

LINQ till DataSet-frågor kan formuleras i två olika syntaxer: frågeuttryckssyntax och metodbaserad frågesyntax.

Syntax för frågeuttryck

Frågeuttryck är en deklarativ frågesyntax. Med den här syntaxen kan en utvecklare skriva frågor i C# eller Visual Basic i ett format som liknar SQL. Genom att använda frågeuttryckssyntax kan du utföra även komplexa filtrerings-, beställnings- och grupperingsåtgärder på datakällor med minimal kod. Mer information finns i LINQ Query Expressions and Basic Query Operations (Visual Basic).

.NET Framework common language runtime (CLR) kan inte läsa själva frågeuttryckets syntax. Vid kompilering översätts därför frågeuttryck till något som CLR förstår: metodanrop. Dessa metoder kallas standardfrågaoperatorer. Som utvecklare kan du anropa dem direkt med hjälp av metodsyntax i stället för att använda frågesyntax. Mer information finns i Frågesyntax och metodsyntax i LINQ. Mer information om vanliga frågeoperatorer finns i Översikt över vanliga frågeoperatorer.

I följande exempel används Select för att returnera alla rader från Product tabellen och visa produktnamnen.

// 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

Metodbaserad frågesyntax

Det andra sättet att formulera LINQ till DataSet-frågor är att använda metodbaserade frågor. Den metodbaserade frågesyntaxen är en sekvens med direkta metodanrop till LINQ-operatormetoder och skickar lambda-uttryck som parametrar. Mer information finns i Lambda-uttryck.

Det här exemplet används Select för att returnera alla rader från Product och visa produktnamnen.

// 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

Skapa frågor

Som tidigare nämnts i det här avsnittet lagrar själva frågevariabeln bara frågekommandona när frågan är utformad för att returnera en sekvens med värden. Om frågan inte innehåller en metod som orsakar omedelbar körning skjuts den faktiska körningen av frågan upp tills du itererar över frågevariabeln i en foreach eller For Each -loop. Med uppskjuten körning kan flera frågor kombineras eller en fråga utökas. När en fråga utökas ändras den så att den inkluderar de nya åtgärderna, och den slutliga körningen återspeglar ändringarna. I följande exempel returnerar den första frågan alla produkter. Den andra frågan utökar den första med hjälp Where av för att returnera alla produkter med storleken "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

När en fråga har körts kan inga ytterligare frågor skapas, och alla efterföljande frågor använder linq-operatorerna i minnet. Frågekörning sker när du itererar över frågevariabeln i en foreach eller For Each -instruktionen, eller genom ett anrop till någon av LINQ-konverteringsoperatorerna som orsakar omedelbar körning. Dessa operatorer omfattar följande: ToList, ToArray, ToLookupoch ToDictionary.

I följande exempel returnerar den första frågan alla produkter som sorteras efter listpris. Metoden ToArray används för att framtvinga omedelbar frågekörning:

// 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

Se även