Dotazy mezi tabulkami (LINQ to DataSet)
Kromě dotazování jedné tabulky můžete také provádět křížové dotazy v LINQ to DataSet. To se provádí pomocí spojení. Spojení je přidružení objektů v jednom zdroji dat k objektům, které sdílejí společný atribut v jiném zdroji dat, například produkt nebo ID kontaktu. V objektově orientovaném programování jsou relace mezi objekty relativně snadné procházet, protože každý objekt má člen, který odkazuje na jiný objekt. V tabulkách externí databáze ale navigace mezi relacemi není tak jednoduchá. Databázové tabulky neobsahují předdefinované relace. V těchto případech lze operaci spojení použít ke shodě prvků z každého zdroje. Například u dvou tabulek, které obsahují informace o produktu a informace o prodeji, můžete pomocí operace spojení spárovat informace o prodeji a produkty pro stejnou prodejní objednávku.
Architektura LINQ (Language-Integrated Query) poskytuje dva operátory spojení a Join GroupJoin. Tyto operátory provádějí koňské spojení: to znamená spojení, která odpovídají dvěma zdrojům dat, pouze pokud jsou jejich klíče stejné. (Naproti tomu jazyk Transact-SQL podporuje jiné operátory spojení, než equals
less than
je například operátor.)
V relačních databázových termínech Join implementuje vnitřní spojení. Vnitřní spojení je typ spojení, ve kterém se vrátí pouze objekty, které mají shodu v opačné sadě dat.
Operátory GroupJoin nemají v relačních databázových termínech přímý ekvivalent. Implementují nadmnožinu vnitřních spojení a levých vnějších spojení. Levé vnější spojení je spojení, které vrací každý prvek první (levé) kolekce, i když neobsahuje žádné korelované prvky ve druhé kolekci.
Další informace o spojeních najdete v tématu Operace spojení.
Příklad
Následující příklad provádí tradiční spojení SalesOrderHeader
a SalesOrderDetail
tabulky z ukázkové databáze AdventureWorks k získání online objednávek z měsíce srpna.
// 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