Condividi tramite


Query su singola tabella (LINQ to DataSet)

Le query LINQ (Language Integrated Query) funzionano su origini dati che implementano l'interfaccia IEnumerable<T> o l'interfaccia IQueryable<T>. Poiché la classe DataTable non implementa nessuna di queste due interfacce, è necessario chiamare il metodo AsEnumerable se si desidera usare DataTable come origine nella clausola From della query LINQ.

Nell'esempio seguente vengono ottenuti tutti gli ordini online della tabella SalesOrderHeader e l'output costituito da ID ordine, data dell'ordine e numero di ordine viene inviato alla console.

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];

var query =
    from order in orders.AsEnumerable()
    where order.Field<bool>("OnlineOrderFlag") == true
    select new
    {
        SalesOrderID = order.Field<int>("SalesOrderID"),
        OrderDate = order.Field<DateTime>("OrderDate"),
        SalesOrderNumber = order.Field<string>("SalesOrderNumber")
    };

foreach (var onlineOrder in query)
{
    Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
        onlineOrder.SalesOrderID,
        onlineOrder.OrderDate,
        onlineOrder.SalesOrderNumber);
}
' 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 orders As DataTable = ds.Tables("SalesOrderHeader")

Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
    Select New With { _
        .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
        .OrderDate = order.Field(Of DateTime)("OrderDate"), _
        .SalesOrderNumber = order.Field(Of String)("SalesOrderNumber") _
     }

For Each onlineOrder In query
    Console.Write("Order ID: " & onlineOrder.SalesOrderID)
    Console.Write(" Order date: " & onlineOrder.OrderDate)
    Console.WriteLine(" Order number: " & onlineOrder.SalesOrderNumber)
Next

La query con variabili locali viene inizializzata con un'espressione di query, che opera su una o più fonti di informazione applicando uno o più operatori di query di tipo standard o, nel caso di LINQ to DataSet, specifici della classe DataSet. Nell'espressione di query dell'esempio precedente vengono usati due operatori di query standard: Where e Select.

La clausola Where filtra la sequenza in base a una condizione, in questo caso che OnlineOrderFlag sia impostato su true. L'operatore Select alloca e restituisce un oggetto enumerabile che acquisisce gli argomenti passati all'operatore. Nell'esempio precedente viene creato un tipo anonimo con tre proprietà: SalesOrderID, OrderDate e SalesOrderNumber. I valori di queste tre proprietà vengono impostati sui valori delle colonne SalesOrderID, OrderDate e SalesOrderNumber della tabella SalesOrderHeader.

Il ciclo foreach enumera quindi gli oggetti enumerabili restituiti da Select e produce i risultati della query. Poiché la query è un tipo Enumerable, che implementa IEnumerable<T>, la valutazione della query viene posticipata finché non viene eseguita un'iterazione della variabile di query in un ciclo foreach. La valutazione posticipata della query consente di mantenere le query come valori che è possibile valutare più volte, ogni volta con un risultato potenzialmente diverso.

Il metodo Field fornisce l'accesso ai valori di colonna di un oggetto DataRow e SetField (non illustrato nell'esempio precedente) imposta i valori di colonna in DataRow. Poiché i metodi Field e SetField gestiscono tipi valori nullable, non è necessario verificare in modo esplicito la presenza di valori Null. Entrambi metodi sono inoltre generici, quindi non è necessario eseguire i cast del tipo restituito. È possibile usare la funzione di accesso della colonna preesistente in DataRow (ad esempio, o["OrderDate"]), ma in questo caso è necessario eseguire il cast dell'oggetto restituito nel tipo appropriato. Se la colonna è un tipo valore nullable, è necessario verificare se il valore è Null usando il metodo IsNull. Per altre informazioni, vedere Metodi Generic Field e SetField.

Si noti che il tipo di dati specificato nel parametro T generico del metodo Field e del metodo SetField deve corrispondere al tipo del valore sottostante; in caso contrario, verrà generata un'eccezione InvalidCastException. Il nome di colonna specificato deve inoltre corrispondere al nome di una colonna presente in DataSet; in caso contrario, verrà generata un'eccezione ArgumentException. In entrambi casi, l'eccezione viene generata in fase di esecuzione durante l'enumerazione dei dati quando viene eseguita la query.

Vedi anche