Zapytania między tabelami (LINQ to DataSet)
Oprócz wykonywania zapytań dotyczących pojedynczej tabeli można również wykonywać zapytania między tabelami w linQ to DataSet. Odbywa się to przy użyciu sprzężenia. Sprzężenie to skojarzenie obiektów w jednym źródle danych z obiektami współużytkujących wspólny atrybut w innym źródle danych, takim jak identyfikator produktu lub kontaktu. W programowaniu obiektowym relacje między obiektami są stosunkowo łatwe do nawigowania, ponieważ każdy obiekt ma składową odwołującą się do innego obiektu. Jednak w zewnętrznych tabelach baz danych nawigowanie po relacjach nie jest tak proste. Tabele baz danych nie zawierają wbudowanych relacji. W takich przypadkach można użyć operacji sprzężenia, aby dopasować elementy z każdego źródła. Na przykład w przypadku dwóch tabel zawierających informacje o produkcie i informacje o sprzedaży można użyć operacji sprzężenia, aby dopasować informacje o sprzedaży i produkty do tego samego zamówienia sprzedaży.
Platforma Zapytań zintegrowanych z językiem (LINQ) udostępnia dwa operatory sprzężenia i Join GroupJoin. Te operatory wykonują sprzężenia równo: oznacza to, że sprzężenia pasujące do dwóch źródeł danych tylko wtedy, gdy ich klucze są równe. (Natomiast język Transact-SQL obsługuje operatory sprzężenia inne niż equals
, takie jak less than
operator).
W terminach Join relacyjnej bazy danych implementuje sprzężenie wewnętrzne. Sprzężenie wewnętrzne jest typem sprzężenia, w którym zwracane są tylko te obiekty, które mają dopasowanie w przeciwnym zestawie danych.
Operatory GroupJoin nie mają bezpośredniego odpowiednika w terminach relacyjnej bazy danych; implementują nadzbiór sprzężeń wewnętrznych i lewe sprzężenia zewnętrzne. Lewe sprzężenie zewnętrzne to sprzężenie zwracające każdy element pierwszej kolekcji (po lewej), nawet jeśli nie ma skorelowanych elementów w drugiej kolekcji.
Aby uzyskać więcej informacji na temat sprzężeń, zobacz Operacje dołączania.
Przykład
Poniższy przykład wykonuje tradycyjne sprzężenie SalesOrderHeader
tabel i SalesOrderDetail
z przykładowej bazy danych AdventureWorks w celu uzyskania zamówień online z miesiąca sierpnia.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable orders = ds.Tables["SalesOrderHeader"];
DataTable details = ds.Tables["SalesOrderDetail"];
var query =
from order in orders.AsEnumerable()
join detail in details.AsEnumerable()
on order.Field<int>("SalesOrderID") equals
detail.Field<int>("SalesOrderID")
where order.Field<bool>("OnlineOrderFlag") == true
&& order.Field<DateTime>("OrderDate").Month == 8
select new
{
SalesOrderID =
order.Field<int>("SalesOrderID"),
SalesOrderDetailID =
detail.Field<int>("SalesOrderDetailID"),
OrderDate =
order.Field<DateTime>("OrderDate"),
ProductID =
detail.Field<int>("ProductID")
};
foreach (var order in query)
{
Console.WriteLine("{0}\t{1}\t{2:d}\t{3}",
order.SalesOrderID,
order.SalesOrderDetailID,
order.OrderDate,
order.ProductID);
}
' 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 details As DataTable = ds.Tables("SalesOrderDetail")
Dim query = _
From order In orders.AsEnumerable() _
Join detail In details.AsEnumerable() _
On order.Field(Of Integer)("SalesOrderID") Equals _
detail.Field(Of Integer)("SalesOrderID") _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
order.Field(Of DateTime)("OrderDate").Month = 8 _
Select New With _
{ _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
.ProductID = detail.Field(Of Integer)("ProductID") _
}
For Each order In query
Console.WriteLine(order.SalesOrderID & vbTab & _
order.SalesOrderDetailID & vbTab & _
order.OrderDate & vbTab & _
order.ProductID)
Next