Consultas de tabela única (LINQ to DataSet)
as consultas LINQ (consulta Language-Integrated) funcionam em fontes de dados que implementam a IEnumerable<T> interface ou a IQueryable<T> interface. A classe DataTable não implementa nenhuma das interfaces, então você deve chamar o método AsEnumerable se quiser usar DataTable como uma origem na cláusula From
de uma consulta do LINQ.
O exemplo a seguir obtém todos os pedidos online da tabela SalesOrderHeader e gera a identificação do pedido, a data do pedido e o número de ordem para o 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
A consulta de variável local é inicializada com uma expressão de consulta, que opera com base em uma ou mais fontes de informações aplicando um ou mais operadores de consulta de um dos operadores de consulta padrão ou, no caso do LINQ to DataSet, os operadores específicos da classe DataSet. A expressão de consulta no exemplo anterior usa dois dos operadores de consulta padrão: Where
e Select
.
A cláusula Where
filtra a sequência com base em uma condição, nesse caso de que OnlineOrderFlag
seja definido como true
. O operador Select
aloca e retorna um objeto enumerável que captura os argumentos passados para o operador. Nesse exemplo acima, um tipo anônimo é criado com três propriedades: SalesOrderID
, OrderDate
e SalesOrderNumber
. Os valores dessas três propriedades são definidos como os valores das colunas SalesOrderID
, OrderDate
e SalesOrderNumber
da tabela SalesOrderHeader
.
O loop foreach
em seguida enumera o objeto enumerável retornado por Select
e produz os resultados da consulta. Como a consulta é um tipo Enumerable, que implementa IEnumerable<T>, a avaliação da consulta é adiada até que a variável de consulta seja iterada usando o loop foreach
. A avaliação da consulta adiada permite que as consultas sejam mantidas como valores que podem ser avaliados várias vezes, cada vez rendendo resultados potencialmente diferentes.
O método Field fornece acesso aos valores de coluna de um DataRow e o SetField (não mostrado no exemplo anterior) define valores de coluna em um DataRow. Os métodos Field e SetField lidam com tipos anuláveis, para você não precise verificar tipos de valores nulos explicitamente. Ambos os métodos também são genéricos, o que significa que você não tem que converter o tipo de retorno. Você pode usar o acessador pré-existente de coluna em DataRow (por exemplo, o["OrderDate"]
), mas fazer isso exige que você converta o objeto de retorno para o tipo apropriado. Se a coluna for anulável, você precisará verificar se o tipo de valor é nulo usando o método IsNull. Para obter mais informações, consulte Métodos De Campo Genérico e SetField.
Observe que o tipo de dados especificado no parâmetro genérico T
dos métodos Field e SetField deve corresponder ao tipo do valor subjacente ou InvalidCastException será gerado. O nome da coluna especificado também deve corresponder ao nome de uma coluna no DataSet ou ArgumentException será gerado. Em ambos os casos, a exceção é gerada na enumeração de dados em tempo de execução quando a consulta é executada.